summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering
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
parent03e12282df9aa1e1fb05a8b90f1cfc2e08764cec (diff)
downloadqtwebkit-ad0d549d4cc13433f77c1ac8f0ab379c83d93f28.tar.gz
Imported WebKit commit bb52bf3c0119e8a128cd93afe5572413a8617de9 (http://svn.webkit.org/repository/webkit/trunk@108790)
Diffstat (limited to 'Source/WebCore/rendering')
-rw-r--r--Source/WebCore/rendering/FilterEffectRenderer.cpp3
-rw-r--r--Source/WebCore/rendering/InlineFlowBox.cpp36
-rw-r--r--Source/WebCore/rendering/InlineFlowBox.h2
-rw-r--r--Source/WebCore/rendering/LayoutState.cpp7
-rw-r--r--Source/WebCore/rendering/LayoutTypes.h22
-rwxr-xr-xSource/WebCore/rendering/RenderBlock.cpp349
-rw-r--r--Source/WebCore/rendering/RenderBlock.h47
-rwxr-xr-xSource/WebCore/rendering/RenderBlockLineLayout.cpp39
-rw-r--r--Source/WebCore/rendering/RenderBox.cpp91
-rw-r--r--Source/WebCore/rendering/RenderBox.h17
-rw-r--r--Source/WebCore/rendering/RenderBoxModelObject.cpp209
-rw-r--r--Source/WebCore/rendering/RenderBoxModelObject.h4
-rw-r--r--Source/WebCore/rendering/RenderButton.cpp13
-rw-r--r--Source/WebCore/rendering/RenderButton.h3
-rw-r--r--Source/WebCore/rendering/RenderDeprecatedFlexibleBox.h1
-rw-r--r--Source/WebCore/rendering/RenderDetailsMarker.cpp2
-rw-r--r--Source/WebCore/rendering/RenderEmbeddedObject.cpp2
-rw-r--r--Source/WebCore/rendering/RenderFieldset.cpp9
-rw-r--r--Source/WebCore/rendering/RenderFileUploadControl.cpp22
-rw-r--r--Source/WebCore/rendering/RenderFileUploadControl.h2
-rw-r--r--Source/WebCore/rendering/RenderFlexibleBox.cpp258
-rw-r--r--Source/WebCore/rendering/RenderFlexibleBox.h18
-rw-r--r--Source/WebCore/rendering/RenderFlowThread.cpp69
-rw-r--r--Source/WebCore/rendering/RenderFlowThread.h8
-rw-r--r--Source/WebCore/rendering/RenderFrameSet.cpp17
-rw-r--r--Source/WebCore/rendering/RenderFrameSet.h8
-rw-r--r--Source/WebCore/rendering/RenderImage.cpp4
-rw-r--r--Source/WebCore/rendering/RenderInline.cpp135
-rw-r--r--Source/WebCore/rendering/RenderLayer.cpp125
-rw-r--r--Source/WebCore/rendering/RenderLayer.h32
-rw-r--r--Source/WebCore/rendering/RenderLayerBacking.cpp177
-rw-r--r--Source/WebCore/rendering/RenderLayerBacking.h20
-rw-r--r--Source/WebCore/rendering/RenderLayerCompositor.cpp142
-rw-r--r--Source/WebCore/rendering/RenderLayerCompositor.h28
-rw-r--r--Source/WebCore/rendering/RenderListBox.cpp10
-rw-r--r--Source/WebCore/rendering/RenderListBox.h2
-rw-r--r--Source/WebCore/rendering/RenderListItem.cpp3
-rw-r--r--Source/WebCore/rendering/RenderListMarker.cpp2
-rw-r--r--Source/WebCore/rendering/RenderMarquee.cpp4
-rw-r--r--Source/WebCore/rendering/RenderMedia.h1
-rw-r--r--Source/WebCore/rendering/RenderMenuList.h4
-rw-r--r--Source/WebCore/rendering/RenderMeter.h1
-rwxr-xr-xSource/WebCore/rendering/RenderObject.cpp118
-rw-r--r--Source/WebCore/rendering/RenderObject.h37
-rw-r--r--Source/WebCore/rendering/RenderObjectChildList.cpp10
-rw-r--r--Source/WebCore/rendering/RenderProgress.h1
-rw-r--r--Source/WebCore/rendering/RenderRegion.cpp5
-rw-r--r--Source/WebCore/rendering/RenderRegion.h11
-rw-r--r--Source/WebCore/rendering/RenderReplaced.cpp2
-rw-r--r--Source/WebCore/rendering/RenderTable.cpp31
-rw-r--r--Source/WebCore/rendering/RenderTable.h2
-rw-r--r--Source/WebCore/rendering/RenderTableCell.cpp24
-rw-r--r--Source/WebCore/rendering/RenderTableCell.h4
-rw-r--r--Source/WebCore/rendering/RenderTableSection.cpp56
-rw-r--r--Source/WebCore/rendering/RenderText.cpp2
-rw-r--r--Source/WebCore/rendering/RenderTextControl.h1
-rw-r--r--Source/WebCore/rendering/RenderTextControlSingleLine.cpp8
-rw-r--r--Source/WebCore/rendering/RenderTextFragment.cpp4
-rw-r--r--Source/WebCore/rendering/RenderTheme.cpp19
-rw-r--r--Source/WebCore/rendering/RenderTheme.h5
-rw-r--r--Source/WebCore/rendering/RenderThemeChromiumAndroid.cpp6
-rw-r--r--Source/WebCore/rendering/RenderThemeChromiumAndroid.h15
-rw-r--r--Source/WebCore/rendering/RenderThemeMac.h4
-rw-r--r--Source/WebCore/rendering/RenderThemeMac.mm10
-rw-r--r--Source/WebCore/rendering/RenderTreeAsText.cpp11
-rw-r--r--Source/WebCore/rendering/RenderWidget.cpp2
-rw-r--r--Source/WebCore/rendering/RootInlineBox.cpp10
-rw-r--r--Source/WebCore/rendering/RootInlineBox.h2
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLBlock.cpp12
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLBlock.h15
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLFenced.cpp16
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLFenced.h5
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp19
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLFraction.h7
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLMath.cpp4
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLMath.h2
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLOperator.cpp16
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLOperator.h7
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLRoot.cpp13
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLRoot.h2
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLRow.cpp57
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLRow.h4
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLSquareRoot.cpp6
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLSquareRoot.h2
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLSubSup.cpp95
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLSubSup.h11
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLUnderOver.cpp67
-rw-r--r--Source/WebCore/rendering/mathml/RenderMathMLUnderOver.h11
-rw-r--r--Source/WebCore/rendering/style/RenderStyle.cpp7
-rw-r--r--Source/WebCore/rendering/style/RenderStyle.h32
-rw-r--r--Source/WebCore/rendering/style/RenderStyleConstants.h6
-rw-r--r--Source/WebCore/rendering/style/StyleCachedImage.cpp13
-rw-r--r--Source/WebCore/rendering/style/StyleCachedImage.h14
-rw-r--r--Source/WebCore/rendering/style/StyleRareInheritedData.cpp18
-rw-r--r--Source/WebCore/rendering/style/StyleRareInheritedData.h6
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGContainer.h1
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGInlineText.cpp2
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp2
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGRoot.cpp2
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGRoot.h2
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGText.cpp7
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGText.h2
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGTransformableContainer.cpp3
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGTransformableContainer.h3
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp25
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGViewportContainer.h7
-rw-r--r--Source/WebCore/rendering/svg/SVGRenderSupport.cpp38
-rw-r--r--Source/WebCore/rendering/svg/SVGRenderSupport.h3
-rw-r--r--Source/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp10
109 files changed, 1854 insertions, 1068 deletions
diff --git a/Source/WebCore/rendering/FilterEffectRenderer.cpp b/Source/WebCore/rendering/FilterEffectRenderer.cpp
index cb20bc4bd..7d9873151 100644
--- a/Source/WebCore/rendering/FilterEffectRenderer.cpp
+++ b/Source/WebCore/rendering/FilterEffectRenderer.cpp
@@ -326,7 +326,8 @@ void FilterEffectRenderer::prepare()
m_graphicsBufferAttached = true;
}
m_sourceGraphic->clearResult();
- lastEffect()->clearResult();
+ for (size_t i = 0; i < m_effects.size(); ++i)
+ m_effects[i]->clearResult();
}
void FilterEffectRenderer::apply()
diff --git a/Source/WebCore/rendering/InlineFlowBox.cpp b/Source/WebCore/rendering/InlineFlowBox.cpp
index fb93b62c2..f799a1ae1 100644
--- a/Source/WebCore/rendering/InlineFlowBox.cpp
+++ b/Source/WebCore/rendering/InlineFlowBox.cpp
@@ -657,8 +657,8 @@ void InlineFlowBox::placeBoxesInBlockDirection(LayoutUnit top, LayoutUnit maxHei
RenderRubyRun* rubyRun = toRenderRubyRun(curr->renderer());
if (RenderRubyBase* rubyBase = rubyRun->rubyBase()) {
- LayoutUnit bottomRubyBaseLeading = (curr->logicalHeight() - rubyBase->logicalBottom()) + rubyBase->logicalHeight() - (rubyBase->lastRootBox() ? rubyBase->lastRootBox()->lineBottom() : 0);
- LayoutUnit topRubyBaseLeading = rubyBase->logicalTop() + (rubyBase->firstRootBox() ? rubyBase->firstRootBox()->lineTop() : 0);
+ LayoutUnit bottomRubyBaseLeading = (curr->logicalHeight() - rubyBase->logicalBottom()) + rubyBase->logicalHeight() - (rubyBase->lastRootBox() ? rubyBase->lastRootBox()->lineBottom() : zeroLayoutUnit);
+ LayoutUnit topRubyBaseLeading = rubyBase->logicalTop() + (rubyBase->firstRootBox() ? rubyBase->firstRootBox()->lineTop() : zeroLayoutUnit);
newLogicalTop += !renderer()->style()->isFlippedLinesWritingMode() ? topRubyBaseLeading : bottomRubyBaseLeading;
boxHeight -= (topRubyBaseLeading + bottomRubyBaseLeading);
}
@@ -787,8 +787,8 @@ inline void InlineFlowBox::addBorderOutsetVisualOverflow(LayoutRect& logicalVisu
LayoutUnit borderOutsetLogicalRight;
style->getBorderImageInlineDirectionOutsets(borderOutsetLogicalLeft, borderOutsetLogicalRight);
- LayoutUnit outsetLogicalLeft = includeLogicalLeftEdge() ? borderOutsetLogicalLeft : 0;
- LayoutUnit outsetLogicalRight = includeLogicalRightEdge() ? borderOutsetLogicalRight : 0;
+ LayoutUnit outsetLogicalLeft = includeLogicalLeftEdge() ? borderOutsetLogicalLeft : zeroLayoutUnit;
+ LayoutUnit outsetLogicalRight = includeLogicalRightEdge() ? borderOutsetLogicalRight : zeroLayoutUnit;
LayoutUnit logicalLeftVisualOverflow = min(pixelSnappedLogicalLeft() - outsetLogicalLeft, logicalVisualOverflow.x());
LayoutUnit logicalRightVisualOverflow = max(pixelSnappedLogicalRight() + outsetLogicalRight, logicalVisualOverflow.maxX());
@@ -1008,7 +1008,7 @@ void InlineFlowBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
flipForWritingMode(overflowRect);
overflowRect.moveBy(paintOffset);
- if (!paintInfo.rect.intersects(overflowRect))
+ if (!paintInfo.rect.intersects(pixelSnappedIntRect(overflowRect)))
return;
if (paintInfo.phase != PaintPhaseChildOutlines) {
@@ -1079,6 +1079,15 @@ void InlineFlowBox::paintFillLayers(const PaintInfo& paintInfo, const Color& c,
paintFillLayer(paintInfo, c, fillLayer, rect, op);
}
+bool InlineFlowBox::boxShadowCanBeAppliedToBackground(const FillLayer& lastBackgroundLayer) const
+{
+ // The checks here match how paintFillLayer() decides whether to clip (if it does, the shadow
+ // would be clipped out, so it has to be drawn separately).
+ StyleImage* image = lastBackgroundLayer.image();
+ bool hasFillImage = image && image->canRender(renderer(), renderer()->style()->effectiveZoom());
+ return (!hasFillImage && !renderer()->style()->hasBorderRadius()) || (!prevLineBox() && !nextLineBox()) || !parent();
+}
+
void InlineFlowBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, const LayoutRect& rect, CompositeOperator op)
{
StyleImage* img = fillLayer->image();
@@ -1107,8 +1116,8 @@ void InlineFlowBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, c
for (InlineFlowBox* curr = this; curr; curr = curr->prevLineBox())
totalLogicalWidth += curr->logicalWidth();
}
- LayoutUnit stripX = rect.x() - (isHorizontal() ? logicalOffsetOnLine : 0);
- LayoutUnit stripY = rect.y() - (isHorizontal() ? 0 : logicalOffsetOnLine);
+ LayoutUnit stripX = rect.x() - (isHorizontal() ? logicalOffsetOnLine : zeroLayoutUnit);
+ LayoutUnit stripY = rect.y() - (isHorizontal() ? zeroLayoutUnit : logicalOffsetOnLine);
LayoutUnit stripWidth = isHorizontal() ? totalLogicalWidth : width();
LayoutUnit stripHeight = isHorizontal() ? height() : totalLogicalWidth;
@@ -1203,7 +1212,8 @@ void InlineFlowBox::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint&
if ((!parent() && m_firstLine && styleToUse != renderer()->style()) || (parent() && renderer()->hasBoxDecorations())) {
LayoutRect paintRect = LayoutRect(adjustedPaintoffset, frameRect.size());
// Shadow comes first and is behind the background and border.
- paintBoxShadow(paintInfo, styleToUse, Normal, paintRect);
+ if (!boxModelObject()->boxShadowShouldBeAppliedToBackground(BackgroundBleedNone, this))
+ paintBoxShadow(paintInfo, styleToUse, Normal, paintRect);
Color c = styleToUse->visitedDependentColor(CSSPropertyBackgroundColor);
paintFillLayers(paintInfo, c, styleToUse->backgroundLayers(), paintRect);
@@ -1237,8 +1247,8 @@ void InlineFlowBox::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint&
LayoutUnit totalLogicalWidth = logicalOffsetOnLine;
for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox())
totalLogicalWidth += curr->logicalWidth();
- LayoutUnit stripX = adjustedPaintoffset.x() - (isHorizontal() ? logicalOffsetOnLine : 0);
- LayoutUnit stripY = adjustedPaintoffset.y() - (isHorizontal() ? 0 : logicalOffsetOnLine);
+ LayoutUnit stripX = adjustedPaintoffset.x() - (isHorizontal() ? logicalOffsetOnLine : zeroLayoutUnit);
+ LayoutUnit stripY = adjustedPaintoffset.y() - (isHorizontal() ? zeroLayoutUnit : logicalOffsetOnLine);
LayoutUnit stripWidth = isHorizontal() ? totalLogicalWidth : frameRect.width();
LayoutUnit stripHeight = isHorizontal() ? frameRect.height() : totalLogicalWidth;
@@ -1308,8 +1318,8 @@ void InlineFlowBox::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffs
LayoutUnit totalLogicalWidth = logicalOffsetOnLine;
for (InlineFlowBox* curr = this; curr; curr = curr->nextLineBox())
totalLogicalWidth += curr->logicalWidth();
- LayoutUnit stripX = adjustedPaintOffset.x() - (isHorizontal() ? logicalOffsetOnLine : 0);
- LayoutUnit stripY = adjustedPaintOffset.y() - (isHorizontal() ? 0 : logicalOffsetOnLine);
+ LayoutUnit stripX = adjustedPaintOffset.x() - (isHorizontal() ? logicalOffsetOnLine : zeroLayoutUnit);
+ LayoutUnit stripY = adjustedPaintOffset.y() - (isHorizontal() ? zeroLayoutUnit : logicalOffsetOnLine);
LayoutUnit stripWidth = isHorizontal() ? totalLogicalWidth : frameRect.width();
LayoutUnit stripHeight = isHorizontal() ? frameRect.height() : totalLogicalWidth;
@@ -1406,7 +1416,7 @@ LayoutUnit InlineFlowBox::computeOverAnnotationAdjustment(LayoutUnit allowedPosi
continue;
if (!rubyRun->style()->isFlippedLinesWritingMode()) {
- LayoutUnit topOfFirstRubyTextLine = rubyText->logicalTop() + (rubyText->firstRootBox() ? rubyText->firstRootBox()->lineTop() : 0);
+ LayoutUnit topOfFirstRubyTextLine = rubyText->logicalTop() + (rubyText->firstRootBox() ? rubyText->firstRootBox()->lineTop() : zeroLayoutUnit);
if (topOfFirstRubyTextLine >= 0)
continue;
topOfFirstRubyTextLine += curr->logicalTop();
diff --git a/Source/WebCore/rendering/InlineFlowBox.h b/Source/WebCore/rendering/InlineFlowBox.h
index 2ea5c47ba..500de7ed9 100644
--- a/Source/WebCore/rendering/InlineFlowBox.h
+++ b/Source/WebCore/rendering/InlineFlowBox.h
@@ -114,6 +114,8 @@ public:
virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom);
+ bool boxShadowCanBeAppliedToBackground(const FillLayer&) const;
+
virtual RenderLineBoxList* rendererLineBoxes() const;
// logicalLeft = left in a horizontal line and top in a vertical line.
diff --git a/Source/WebCore/rendering/LayoutState.cpp b/Source/WebCore/rendering/LayoutState.cpp
index c9018c599..e89dcc5db 100644
--- a/Source/WebCore/rendering/LayoutState.cpp
+++ b/Source/WebCore/rendering/LayoutState.cpp
@@ -79,7 +79,7 @@ LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const LayoutSiz
m_clipped = true;
}
- m_paintOffset -= layer->scrolledContentOffset();
+ m_paintOffset -= renderer->scrolledContentOffset();
}
// If we establish a new page height, then cache the offset to the top of the first page.
@@ -156,10 +156,11 @@ LayoutState::LayoutState(RenderObject* root)
m_paintOffset = LayoutSize(absContentPoint.x(), absContentPoint.y());
if (container->hasOverflowClip()) {
- RenderLayer* layer = toRenderBoxModelObject(container)->layer();
+ RenderBox* containerBox = toRenderBox(container);
+ RenderLayer* layer = containerBox->layer();
m_clipped = true;
m_clipRect = LayoutRect(toPoint(m_paintOffset), layer->size());
- m_paintOffset -= layer->scrolledContentOffset();
+ m_paintOffset -= containerBox->scrolledContentOffset();
}
}
diff --git a/Source/WebCore/rendering/LayoutTypes.h b/Source/WebCore/rendering/LayoutTypes.h
index fc765d11f..72cbf2fd9 100644
--- a/Source/WebCore/rendering/LayoutTypes.h
+++ b/Source/WebCore/rendering/LayoutTypes.h
@@ -46,16 +46,38 @@ typedef IntPoint LayoutPoint;
typedef IntSize LayoutSize;
typedef IntRect LayoutRect;
+const LayoutUnit zeroLayoutUnit = 0;
+
inline LayoutRect enclosingLayoutRect(const FloatRect& rect)
{
return enclosingIntRect(rect);
}
+inline IntRect pixelSnappedIntRect(const LayoutRect& rect)
+{
+ return rect;
+}
+
+inline IntRect pixelSnappedIntRectFromEdges(LayoutUnit left, LayoutUnit top, LayoutUnit right, LayoutUnit bottom)
+{
+ return IntRect(left, top, right - left, bottom - top);
+}
+
+inline IntSize roundedIntSize(const LayoutSize& s)
+{
+ return s;
+}
+
inline LayoutSize roundedLayoutSize(const FloatSize& s)
{
return roundedIntSize(s);
}
+inline IntPoint roundedIntPoint(const LayoutPoint& p)
+{
+ return p;
+}
+
inline LayoutPoint roundedLayoutPoint(const FloatPoint& p)
{
return roundedIntPoint(p);
diff --git a/Source/WebCore/rendering/RenderBlock.cpp b/Source/WebCore/rendering/RenderBlock.cpp
index 9b2bca5a9..413c60ece 100755
--- a/Source/WebCore/rendering/RenderBlock.cpp
+++ b/Source/WebCore/rendering/RenderBlock.cpp
@@ -114,8 +114,8 @@ RenderBlock::MarginInfo::MarginInfo(RenderBlock* block, LayoutUnit beforeBorderP
m_quirkContainer = block->isTableCell() || block->isBody() || blockStyle->marginBeforeCollapse() == MDISCARD
|| blockStyle->marginAfterCollapse() == MDISCARD;
- m_positiveMargin = m_canCollapseMarginBeforeWithChildren ? block->maxPositiveMarginBefore() : 0;
- m_negativeMargin = m_canCollapseMarginBeforeWithChildren ? block->maxNegativeMarginBefore() : 0;
+ m_positiveMargin = m_canCollapseMarginBeforeWithChildren ? block->maxPositiveMarginBefore() : zeroLayoutUnit;
+ m_negativeMargin = m_canCollapseMarginBeforeWithChildren ? block->maxNegativeMarginBefore() : zeroLayoutUnit;
}
// -------------------------------------------------------------------------------------------------------
@@ -429,14 +429,24 @@ void RenderBlock::addChildToAnonymousColumnBlocks(RenderObject* newChild, Render
RenderBlock* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBlock)
{
+ RenderBlock* firstChildIgnoringAnonymousWrappers = 0;
for (RenderObject* curr = this; curr; curr = curr->parent()) {
if (!curr->isRenderBlock() || curr->isFloatingOrPositioned() || curr->isTableCell() || curr->isRoot() || curr->isRenderView() || curr->hasOverflowClip()
|| curr->isInlineBlockOrInlineTable())
return 0;
+
+ // FIXME: Table manages its own table parts, most of which are RenderBoxes.
+ // Multi-column code cannot handle splitting the flow in table. Disabling it
+ // to prevent crashes.
+ if (curr->isTable())
+ return 0;
RenderBlock* currBlock = toRenderBlock(curr);
+ if (!currBlock->createsAnonymousWrapper())
+ firstChildIgnoringAnonymousWrappers = currBlock;
+
if (currBlock->style()->specifiesColumns() && (allowAnonymousColumnBlock || !currBlock->isAnonymousColumnsBlock()))
- return currBlock;
+ return firstChildIgnoringAnonymousWrappers;
if (currBlock->isAnonymousColumnSpanBlock())
return 0;
@@ -447,15 +457,20 @@ RenderBlock* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBlock)
RenderBlock* RenderBlock::clone() const
{
RenderBlock* cloneBlock;
- if (isAnonymousBlock())
+ if (isAnonymousBlock()) {
cloneBlock = createAnonymousBlock();
+ cloneBlock->setChildrenInline(childrenInline());
+ }
else {
- cloneBlock = new (renderArena()) RenderBlock(node());
+ RenderObject* cloneRenderer = node()->createRenderer(renderArena(), style());
+ cloneBlock = toRenderBlock(cloneRenderer);
cloneBlock->setStyle(style());
- if (!childrenInline() && cloneBlock->firstChild() && cloneBlock->firstChild()->isInline())
- cloneBlock->makeChildrenNonInline();
+
+ // This takes care of setting the right value of childrenInline in case
+ // generated content is added to cloneBlock and 'this' does not have
+ // generated content added yet.
+ cloneBlock->setChildrenInline(cloneBlock->firstChild() ? cloneBlock->firstChild()->isInline() : childrenInline());
}
- cloneBlock->setChildrenInline(childrenInline());
return cloneBlock;
}
@@ -468,10 +483,16 @@ void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
if (!isAnonymousBlock())
cloneBlock->setContinuation(oldCont);
- // Now take all of the children from beforeChild to the end and remove
- // them from |this| and place them in the clone.
if (!beforeChild && isAfterContent(lastChild()))
beforeChild = lastChild();
+
+ // If we are moving inline children from |this| to cloneBlock, then we need
+ // to clear our line box tree.
+ if (beforeChild && childrenInline())
+ deleteLineBoxTree();
+
+ // Now take all of the children from beforeChild to the end and remove
+ // them from |this| and place them in the clone.
moveChildrenTo(cloneBlock, beforeChild, 0, true);
// Hook |clone| up as the continuation of the middle block.
@@ -494,7 +515,7 @@ void RenderBlock::splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock,
cloneBlock = blockCurr->clone();
// Insert our child clone as the first child.
- cloneBlock->children()->appendChildNode(cloneBlock, cloneChild);
+ cloneBlock->addChildIgnoringContinuation(cloneChild, 0);
// Hook the clone up as a continuation of |curr|. Note we do encounter
// anonymous blocks possibly as we walk up the block chain. When we split an
@@ -585,6 +606,9 @@ void RenderBlock::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
RenderObject* RenderBlock::splitAnonymousBlocksAroundChild(RenderObject* beforeChild)
{
+ if (beforeChild->isTablePart())
+ beforeChild = splitTablePartsAroundChild(beforeChild);
+
while (beforeChild->parent() != this) {
RenderBlock* blockToSplit = toRenderBlock(beforeChild->parent());
if (blockToSplit->firstChild() != beforeChild) {
@@ -603,6 +627,71 @@ RenderObject* RenderBlock::splitAnonymousBlocksAroundChild(RenderObject* beforeC
return beforeChild;
}
+static void markTableForSectionAndCellRecalculation(RenderObject* child)
+{
+ RenderObject* curr = child;
+ while (!curr->isTable()) {
+ if (curr->isTableSection())
+ toRenderTableSection(curr)->setNeedsCellRecalc();
+ curr = curr->parent();
+ }
+
+ RenderTable* table = toRenderTable(curr);
+ table->setNeedsSectionRecalc();
+ table->setNeedsLayoutAndPrefWidthsRecalc();
+}
+
+static void moveAllTableChildrenTo(RenderObject* fromTablePart, RenderTable* toTable, RenderObject* startChild)
+{
+ for (RenderObject* curr = startChild; curr;) {
+ // Need to store next sibling as we won't have access to it
+ // after we are removed from table.
+ RenderObject* next = curr->nextSibling();
+ fromTablePart->removeChild(curr);
+ toTable->addChild(curr);
+ if (curr->isTableSection())
+ toRenderTableSection(curr)->setNeedsCellRecalc();
+ curr->setNeedsLayoutAndPrefWidthsRecalc();
+ curr = next;
+ }
+
+ // This marks fromTable for section and cell recalculation.
+ markTableForSectionAndCellRecalculation(fromTablePart);
+
+ // startChild is now part of toTable. This marks toTable for section and cell recalculation.
+ markTableForSectionAndCellRecalculation(startChild);
+}
+
+RenderObject* RenderBlock::splitTablePartsAroundChild(RenderObject* beforeChild)
+{
+ ASSERT(beforeChild->isTablePart());
+
+ while (beforeChild->parent() != this) {
+ RenderObject* tablePartToSplit = beforeChild->parent();
+ if (!tablePartToSplit->isTablePart() && !tablePartToSplit->isTable())
+ break;
+ if (tablePartToSplit->firstChild() != beforeChild) {
+ // Get our table container.
+ RenderObject* curr = tablePartToSplit;
+ while (!curr->isTable())
+ curr = curr->parent();
+ RenderTable* table = toRenderTable(curr);
+
+ // Create an anonymous table container next to our table container.
+ RenderBlock* parentBlock = toRenderBlock(table->parent());
+ RenderTable* postTable = parentBlock->createAnonymousTable();
+ parentBlock->children()->insertChildNode(parentBlock, postTable, table->nextSibling());
+
+ // Move all the children from beforeChild to the newly created anonymous table container.
+ moveAllTableChildrenTo(tablePartToSplit, postTable, beforeChild);
+
+ beforeChild = postTable;
+ } else
+ beforeChild = tablePartToSplit;
+ }
+ return beforeChild;
+}
+
void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlock* newBlockBox, RenderObject* newChild)
{
RenderBlock* pre = 0;
@@ -669,22 +758,17 @@ RenderBlock* RenderBlock::columnsBlockForSpanningElement(RenderObject* newChild)
RenderBlock* columnsBlockAncestor = 0;
if (!newChild->isText() && newChild->style()->columnSpan() && !newChild->isBeforeOrAfterContent()
&& !newChild->isFloatingOrPositioned() && !newChild->isInline() && !isAnonymousColumnSpanBlock()) {
- if (style()->specifiesColumns())
- columnsBlockAncestor = this;
- else if (!isInline() && parent() && parent()->isRenderBlock()) {
- columnsBlockAncestor = toRenderBlock(parent())->containingColumnsBlock(false);
-
- if (columnsBlockAncestor) {
- // Make sure that none of the parent ancestors have a continuation.
- // If yes, we do not want split the block into continuations.
- RenderObject* curr = this;
- while (curr && curr != columnsBlockAncestor) {
- if (curr->isRenderBlock() && toRenderBlock(curr)->continuation()) {
- columnsBlockAncestor = 0;
- break;
- }
- curr = curr->parent();
+ columnsBlockAncestor = containingColumnsBlock(false);
+ if (columnsBlockAncestor) {
+ // Make sure that none of the parent ancestors have a continuation.
+ // If yes, we do not want split the block into continuations.
+ RenderObject* curr = this;
+ while (curr && curr != columnsBlockAncestor) {
+ if (curr->isRenderBlock() && toRenderBlock(curr)->continuation()) {
+ columnsBlockAncestor = 0;
+ break;
}
+ curr = curr->parent();
}
}
}
@@ -697,35 +781,48 @@ void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild,
if (!beforeChild)
beforeChild = afterPseudoElementRenderer();
- // If the requested beforeChild is not one of our children, then this is because
- // there is an anonymous container within this object that contains the beforeChild.
if (beforeChild && beforeChild->parent() != this) {
- RenderObject* beforeChildAnonymousContainer = anonymousContainer(beforeChild);
- ASSERT(beforeChildAnonymousContainer);
- ASSERT(beforeChildAnonymousContainer->isAnonymous());
-
- if (beforeChildAnonymousContainer->isAnonymousBlock()) {
- // Insert the child into the anonymous block box instead of here.
- if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
- beforeChild->parent()->addChild(newChild, beforeChild);
- else
- addChild(newChild, beforeChild->parent());
- return;
- }
+ RenderObject* beforeChildContainer = beforeChild->parent();
+ while (beforeChildContainer->parent() != this)
+ beforeChildContainer = beforeChildContainer->parent();
+ ASSERT(beforeChildContainer);
+
+ if (beforeChildContainer->isAnonymous()) {
+ // If the requested beforeChild is not one of our children, then this is because
+ // there is an anonymous container within this object that contains the beforeChild.
+ RenderObject* beforeChildAnonymousContainer = beforeChildContainer;
+ if (beforeChildAnonymousContainer->isAnonymousBlock()) {
+ // Insert the child into the anonymous block box instead of here.
+ if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
+ beforeChild->parent()->addChild(newChild, beforeChild);
+ else
+ addChild(newChild, beforeChild->parent());
+ return;
+ }
- ASSERT(beforeChildAnonymousContainer->isTable());
- if ((newChild->isTableCol() && newChild->style()->display() == TABLE_COLUMN_GROUP)
- || (newChild->isTableCaption())
- || newChild->isTableSection()
- || newChild->isTableRow()
- || newChild->isTableCell()) {
- // Insert into the anonymous table.
- beforeChildAnonymousContainer->addChild(newChild, beforeChild);
- return;
- }
+ ASSERT(beforeChildAnonymousContainer->isTable());
+ if (newChild->isTablePart()) {
+ // Insert into the anonymous table.
+ beforeChildAnonymousContainer->addChild(newChild, beforeChild);
+ return;
+ }
+
+ beforeChild = splitTablePartsAroundChild(beforeChild);
- // Go on to insert before the anonymous table.
- beforeChild = beforeChildAnonymousContainer;
+ ASSERT(beforeChild->parent() == this);
+ if (beforeChild->parent() != this) {
+ // We should never reach here. If we do, we need to use the
+ // safe fallback to use the topmost beforeChild container.
+ beforeChild = beforeChildContainer;
+ }
+ } else {
+ // We will reach here when beforeChild is a run-in element.
+ // If run-in element precedes a block-level element, it becomes the
+ // the first inline child of that block level element. The insertion
+ // point will be before that block-level element.
+ ASSERT(beforeChild->isRunIn());
+ beforeChild = beforeChildContainer;
+ }
}
// Check for a spanning element in columns.
@@ -885,23 +982,27 @@ RootInlineBox* RenderBlock::createAndAppendRootInlineBox()
return rootBox;
}
-void RenderBlock::moveChildTo(RenderBlock* to, RenderObject* child, RenderObject* beforeChild, bool fullRemoveInsert)
+void RenderBlock::moveChildTo(RenderBlock* toBlock, RenderObject* child, RenderObject* beforeChild, bool fullRemoveInsert)
{
ASSERT(this == child->parent());
- ASSERT(!beforeChild || to == beforeChild->parent());
- to->children()->insertChildNode(to, children()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert);
+ ASSERT(!beforeChild || toBlock == beforeChild->parent());
+ if (fullRemoveInsert) {
+ // Takes care of adding the new child correctly if toBlock and fromBlock
+ // have different kind of children (block vs inline).
+ toBlock->addChildIgnoringContinuation(children()->removeChildNode(this, child), beforeChild);
+ } else
+ toBlock->children()->insertChildNode(toBlock, children()->removeChildNode(this, child, false), beforeChild, false);
}
-void RenderBlock::moveChildrenTo(RenderBlock* to, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert)
+void RenderBlock::moveChildrenTo(RenderBlock* toBlock, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert)
{
- ASSERT(!beforeChild || to == beforeChild->parent());
- RenderObject* nextChild = startChild;
- while (nextChild && nextChild != endChild) {
- RenderObject* child = nextChild;
- nextChild = child->nextSibling();
- to->children()->insertChildNode(to, children()->removeChildNode(this, child, fullRemoveInsert), beforeChild, fullRemoveInsert);
- if (child == endChild)
- return;
+ ASSERT(!beforeChild || toBlock == beforeChild->parent());
+
+ for (RenderObject* child = startChild; child && child != endChild; ) {
+ // Save our next sibling as moveChildTo will clear it.
+ RenderObject* nextSibling = child->nextSibling();
+ moveChildTo(toBlock, child, beforeChild, fullRemoveInsert);
+ child = nextSibling;
}
}
@@ -1025,11 +1126,15 @@ void RenderBlock::collapseAnonymousBoxChild(RenderBlock* parent, RenderObject* c
parent->setNeedsLayoutAndPrefWidthsRecalc();
parent->setChildrenInline(child->childrenInline());
RenderObject* nextSibling = child->nextSibling();
+
+ RenderFlowThread* childFlowThread = child->enclosingRenderFlowThread();
RenderBlock* anonBlock = toRenderBlock(parent->children()->removeChildNode(parent, child, child->hasLayer()));
anonBlock->moveAllChildrenTo(parent, nextSibling, child->hasLayer());
// Delete the now-empty block's lines and nuke it.
if (!parent->documentBeingDestroyed())
anonBlock->deleteLineBoxTree();
+ if (childFlowThread && !parent->documentBeingDestroyed())
+ childFlowThread->removeFlowChildInfo(anonBlock);
anonBlock->destroy();
}
@@ -1419,7 +1524,7 @@ void RenderBlock::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeigh
if (hasOverflowClip()) {
// Adjust repaint rect for scroll offset
- repaintRect.move(-layer()->scrolledContentOffset());
+ repaintRect.move(-scrolledContentOffset());
// Don't allow this rect to spill out of our overflow box.
repaintRect.intersect(LayoutRect(LayoutPoint(), size()));
@@ -1427,7 +1532,6 @@ void RenderBlock::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeigh
// Make sure the rect is still non-empty after intersecting for overflow above
if (!repaintRect.isEmpty()) {
- // FIXME: Might need rounding once we switch to float, see https://bugs.webkit.org/show_bug.cgi?id=64021
repaintRectangle(repaintRect); // We need to do a partial repaint of our content.
if (hasReflection())
repaintRectangle(reflectedRect(repaintRect));
@@ -1488,6 +1592,9 @@ void RenderBlock::computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeF
// Add visual overflow from theme.
addVisualOverflowFromTheme();
+
+ if (isRenderFlowThread())
+ enclosingRenderFlowThread()->computeOverflowStateForRegions(oldClientAfterEdge);
}
void RenderBlock::addOverflowFromBlockChildren()
@@ -1591,7 +1698,7 @@ void RenderBlock::adjustFloatingBlock(const MarginInfo& marginInfo)
// for by simply calling canCollapseWithMarginBefore. See
// http://www.hixie.ch/tests/adhoc/css/box/block/margin-collapse/046.html for
// an example of this scenario.
- LayoutUnit marginOffset = marginInfo.canCollapseWithMarginBefore() ? 0 : marginInfo.margin();
+ LayoutUnit marginOffset = marginInfo.canCollapseWithMarginBefore() ? zeroLayoutUnit : marginInfo.margin();
setLogicalHeight(logicalHeight() + marginOffset);
positionNewFloats();
setLogicalHeight(logicalHeight() - marginOffset);
@@ -1893,7 +2000,6 @@ LayoutUnit RenderBlock::computeStartPositionDeltaForChildAvoidingFloats(const Re
if (childMarginStart < 0)
startOff += childMarginStart;
newPosition = max(newPosition, startOff); // Let the float sit in the child's margin if it can fit.
- // FIXME: Needs to use epsilon once we switch to float, see https://bugs.webkit.org/show_bug.cgi?id=64021
} else if (startOff != startPosition) {
// The object is shifting to the "end" side of the block. The object might be centered, so we need to
// recalculate our inline direction margins. Note that the containing block content
@@ -2440,7 +2546,7 @@ void RenderBlock::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
// z-index. We paint after we painted the background/border, so that the scrollbars will
// sit above the background/border.
if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.shouldPaintWithinRoot(this))
- layer()->paintOverflowControls(paintInfo.context, adjustedPaintOffset, paintInfo.rect);
+ layer()->paintOverflowControls(paintInfo.context, roundedIntPoint(adjustedPaintOffset), paintInfo.rect);
}
void RenderBlock::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
@@ -2463,9 +2569,9 @@ void RenderBlock::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& pain
bool antialias = shouldAntialiasLines(paintInfo.context);
if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
- LayoutUnit currLogicalLeftOffset = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth();
+ LayoutUnit currLogicalLeftOffset = style()->isLeftToRightDirection() ? zeroLayoutUnit : contentLogicalWidth();
LayoutUnit ruleAdd = logicalLeftOffsetForContent();
- LayoutUnit ruleLogicalLeft = style()->isLeftToRightDirection() ? 0 : contentLogicalWidth();
+ LayoutUnit ruleLogicalLeft = style()->isLeftToRightDirection() ? zeroLayoutUnit : contentLogicalWidth();
LayoutUnit inlineDirectionSize = colInfo->desiredColumnWidth();
BoxSide boxSide = isHorizontalWritingMode()
? style()->isLeftToRightDirection() ? BSLeft : BSRight
@@ -2487,7 +2593,8 @@ void RenderBlock::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& pain
LayoutUnit ruleRight = isHorizontalWritingMode() ? ruleLeft + ruleThickness : ruleLeft + contentWidth();
LayoutUnit ruleTop = isHorizontalWritingMode() ? paintOffset.y() + borderTop() + paddingTop() : paintOffset.y() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd;
LayoutUnit ruleBottom = isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleThickness;
- drawLineForBoxSide(paintInfo.context, ruleLeft, ruleTop, ruleRight, ruleBottom, boxSide, ruleColor, ruleStyle, 0, 0, antialias);
+ IntRect pixelSnappedRuleRect = pixelSnappedIntRectFromEdges(ruleLeft, ruleTop, ruleRight, ruleBottom);
+ drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
}
ruleLogicalLeft = currLogicalLeftOffset;
@@ -2512,7 +2619,8 @@ void RenderBlock::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& pain
for (unsigned i = 1; i < colCount; i++) {
ruleRect.move(step);
- drawLineForBoxSide(paintInfo.context, ruleRect.x(), ruleRect.y(), ruleRect.maxX(), ruleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
+ IntRect pixelSnappedRuleRect = pixelSnappedIntRect(ruleRect);
+ drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
}
}
}
@@ -2540,7 +2648,7 @@ void RenderBlock::paintColumnContents(PaintInfo& paintInfo, const LayoutPoint& p
}
colRect.moveBy(paintOffset);
PaintInfo info(paintInfo);
- info.rect.intersect(colRect);
+ info.rect.intersect(pixelSnappedIntRect(colRect));
if (!info.rect.isEmpty()) {
GraphicsContextStateSaver stateSaver(*context);
@@ -2680,7 +2788,7 @@ void RenderBlock::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffs
// Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).
LayoutPoint scrolledOffset = paintOffset;
if (hasOverflowClip())
- scrolledOffset.move(-layer()->scrolledContentOffset());
+ scrolledOffset.move(-scrolledContentOffset());
// 2. paint contents
if (paintPhase != PaintPhaseSelfOutline) {
@@ -2928,7 +3036,7 @@ GapRects RenderBlock::selectionGapRectsForRepaint(RenderBoxModelObject* repaintC
LayoutPoint offsetFromRepaintContainer = roundedLayoutPoint(transformState.mappedPoint());
if (hasOverflowClip())
- offsetFromRepaintContainer -= layer()->scrolledContentOffset();
+ offsetFromRepaintContainer -= scrolledContentOffset();
LayoutUnit lastTop = 0;
LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop);
@@ -2953,7 +3061,8 @@ void RenderBlock::paintSelection(PaintInfo& paintInfo, const LayoutPoint& paintO
LayoutRect localBounds(gapRectsBounds);
flipForWritingMode(localBounds);
gapRectsBounds = localToContainerQuad(FloatRect(localBounds), layer->renderer()).enclosingBoundingBox();
- gapRectsBounds.move(layer->scrolledContentOffset());
+ if (layer->renderer()->hasOverflowClip())
+ gapRectsBounds.move(layer->renderBox()->scrolledContentOffset());
}
layer->addBlockSelectionGapsBounds(gapRectsBounds);
}
@@ -3019,7 +3128,7 @@ GapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const LayoutPoint& r
r->m_renderer->width(), r->m_renderer->height());
rootBlock->flipForWritingMode(floatBox);
floatBox.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPosition.y());
- paintInfo->context->clipOut(floatBox);
+ paintInfo->context->clipOut(pixelSnappedIntRect(floatBox));
}
}
}
@@ -3769,7 +3878,7 @@ LayoutUnit RenderBlock::nextFloatLogicalBottomBelow(LayoutUnit logicalHeight) co
bottom = min(floatBottom, bottom);
}
- return bottom == numeric_limits<LayoutUnit>::max() ? 0 : bottom;
+ return bottom == numeric_limits<LayoutUnit>::max() ? zeroLayoutUnit : bottom;
}
LayoutUnit RenderBlock::lowestFloatLogicalBottom(FloatingObject::Type floatType) const
@@ -4087,7 +4196,7 @@ bool RenderBlock::avoidsFloats() const
return RenderBox::avoidsFloats() || !style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth();
}
-bool RenderBlock::containsFloat(RenderBox* renderer)
+bool RenderBlock::containsFloat(RenderBox* renderer) const
{
return m_floatingObjects && m_floatingObjects->set().contains<RenderBox*, FloatingObjectHashTranslator>(renderer);
}
@@ -4166,13 +4275,11 @@ LayoutUnit RenderBlock::getClearDelta(RenderBox* child, LayoutUnit logicalTop)
}
// We also clear floats if we are too big to sit on the same line as a float (and wish to avoid floats by default).
- LayoutUnit result = clearSet ? max<LayoutUnit>(0, logicalBottom - logicalTop) : 0;
+ LayoutUnit result = clearSet ? max<LayoutUnit>(0, logicalBottom - logicalTop) : zeroLayoutUnit;
if (!result && child->avoidsFloats()) {
LayoutUnit newLogicalTop = logicalTop;
while (true) {
LayoutUnit availableLogicalWidthAtNewLogicalTopOffset = availableLogicalWidthForLine(newLogicalTop, false);
- // FIXME: Change to use roughlyEquals when we move to float.
- // See https://bugs.webkit.org/show_bug.cgi?id=66148
if (availableLogicalWidthAtNewLogicalTopOffset == availableLogicalWidthForContent(newLogicalTop))
return newLogicalTop - logicalTop;
@@ -4193,8 +4300,6 @@ LayoutUnit RenderBlock::getClearDelta(RenderBox* child, LayoutUnit logicalTop)
child->setMarginLeft(childOldMarginLeft);
child->setMarginRight(childOldMarginRight);
- // FIXME: Change to use roughlyEquals when we move to float.
- // See https://bugs.webkit.org/show_bug.cgi?id=66148
if (childLogicalWidthAtNewLogicalTopOffset <= availableLogicalWidthAtNewLogicalTopOffset)
return newLogicalTop - logicalTop;
@@ -4245,9 +4350,8 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
if (checkChildren) {
// Hit test descendants first.
LayoutSize scrolledOffset(localOffset);
- if (hasOverflowClip()) {
- scrolledOffset -= layer()->scrolledContentOffset();
- }
+ if (hasOverflowClip())
+ scrolledOffset -= scrolledContentOffset();
// Hit test contents if we don't have columns.
if (!hasColumns()) {
@@ -4594,7 +4698,7 @@ VisiblePosition RenderBlock::positionForPoint(const LayoutPoint& point)
void RenderBlock::offsetForContents(LayoutPoint& offset) const
{
if (hasOverflowClip())
- offset += layer()->scrolledContentOffset();
+ offset += scrolledContentOffset();
if (hasColumns())
adjustPointToColumnContents(offset);
@@ -5005,6 +5109,8 @@ void RenderBlock::computePreferredLogicalWidths()
}
int scrollbarWidth = 0;
+ // FIXME: This should only be done for horizontal writing mode.
+ // For vertical writing mode, this should check overflowX and use the horizontalScrollbarHeight.
if (hasOverflowClip() && styleToUse->overflowY() == OSCROLL) {
layer()->setHasVerticalScrollbar(true);
scrollbarWidth = verticalScrollbarWidth();
@@ -5150,7 +5256,7 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
RenderStyle* styleToUse = style();
RenderBlock* containingBlock = this->containingBlock();
- LayoutUnit cw = containingBlock ? containingBlock->contentLogicalWidth() : 0;
+ LayoutUnit cw = containingBlock ? containingBlock->contentLogicalWidth() : zeroLayoutUnit;
// If we are at the start of a line, we want to ignore all white-space.
// Also strip spaces if we previously had text that ended in a trailing space.
@@ -5704,6 +5810,36 @@ static inline bool shouldSkipForFirstLetter(UChar c)
return isSpaceOrNewline(c) || c == noBreakSpace || isPunctuationForFirstLetter(c);
}
+// We only honor first-letter if
+// - the firstLetterBlock can have children in the DOM and
+// - the block doesn't have any special assumption on its text children.
+// This correctly prevents form controls from honoring first-letter.
+static inline bool isSafeToCreateFirstLetterRendererOn(RenderObject* renderer)
+{
+ return (renderer->canHaveChildren()
+ && !(renderer->isDeprecatedFlexibleBox()
+ && static_cast<RenderDeprecatedFlexibleBox*>(renderer)->buttonText()));
+}
+
+static inline RenderObject* findFirstLetterBlock(RenderBlock* start)
+{
+ RenderObject* firstLetterBlock = start;
+ while (true) {
+ bool canHaveFirstLetterRenderer = firstLetterBlock->style()->hasPseudoStyle(FIRST_LETTER)
+ && isSafeToCreateFirstLetterRendererOn(firstLetterBlock);
+ if (canHaveFirstLetterRenderer)
+ return firstLetterBlock;
+
+ RenderObject* parentBlock = firstLetterBlock->parent();
+ if (firstLetterBlock->isReplaced() || !parentBlock || parentBlock->firstChild() != firstLetterBlock ||
+ !parentBlock->isBlockFlow())
+ return 0;
+ firstLetterBlock = parentBlock;
+ }
+
+ return 0;
+}
+
void RenderBlock::updateFirstLetter()
{
if (!document()->usesFirstLetterRules())
@@ -5714,23 +5850,8 @@ void RenderBlock::updateFirstLetter()
// FIXME: We need to destroy the first-letter object if it is no longer the first child. Need to find
// an efficient way to check for that situation though before implementing anything.
- RenderObject* firstLetterBlock = this;
- bool hasPseudoStyle = false;
- while (true) {
- // We only honor first-letter if the firstLetterBlock can have children in the DOM. This correctly
- // prevents form controls from honoring first-letter.
- hasPseudoStyle = firstLetterBlock->style()->hasPseudoStyle(FIRST_LETTER)
- && firstLetterBlock->canHaveChildren();
- if (hasPseudoStyle)
- break;
- RenderObject* parentBlock = firstLetterBlock->parent();
- if (firstLetterBlock->isReplaced() || !parentBlock || parentBlock->firstChild() != firstLetterBlock ||
- !parentBlock->isBlockFlow())
- break;
- firstLetterBlock = parentBlock;
- }
-
- if (!hasPseudoStyle)
+ RenderObject* firstLetterBlock = findFirstLetterBlock(this);
+ if (!firstLetterBlock)
return;
// Drill into inlines looking for our first text child.
@@ -5922,7 +6043,7 @@ static int getHeightForLineCount(RenderBlock* block, int l, bool includeBottom,
if (block->childrenInline()) {
for (RootInlineBox* box = block->firstRootBox(); box; box = box->nextRootBox()) {
if (++count == l)
- return box->lineBottom() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : 0);
+ return box->lineBottom() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : zeroLayoutUnit);
}
}
else {
@@ -5931,7 +6052,7 @@ static int getHeightForLineCount(RenderBlock* block, int l, bool includeBottom,
if (shouldCheckLines(obj)) {
int result = getHeightForLineCount(toRenderBlock(obj), l, false, count);
if (result != -1)
- return result + obj->y() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : 0);
+ return result + obj->y() + (includeBottom ? (block->borderBottom() + block->paddingBottom()) : zeroLayoutUnit);
}
else if (!obj->isFloatingOrPositioned() && !obj->isRunIn())
normalFlowChildWithoutLines = obj;
@@ -6495,11 +6616,15 @@ LayoutUnit RenderBlock::pageRemainingLogicalHeightForOffset(LayoutUnit offset, P
LayoutUnit RenderBlock::adjustForUnsplittableChild(RenderBox* child, LayoutUnit logicalOffset, bool includeMargins)
{
- bool isUnsplittable = child->isUnsplittableForPagination() || child->style()->columnBreakInside() == PBAVOID
- || child->style()->regionBreakInside() == PBAVOID;
+ bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
+ bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight;
+ bool checkRegionBreaks = inRenderFlowThread();
+ bool isUnsplittable = child->isUnsplittableForPagination() || (checkColumnBreaks && child->style()->columnBreakInside() == PBAVOID)
+ || (checkPageBreaks && child->style()->pageBreakInside() == PBAVOID)
+ || (checkRegionBreaks && child->style()->regionBreakInside() == PBAVOID);
if (!isUnsplittable)
return logicalOffset;
- LayoutUnit childLogicalHeight = logicalHeightForChild(child) + (includeMargins ? marginBeforeForChild(child) + marginAfterForChild(child) : 0);
+ LayoutUnit childLogicalHeight = logicalHeightForChild(child) + (includeMargins ? marginBeforeForChild(child) + marginAfterForChild(child) : zeroLayoutUnit);
LayoutState* layoutState = view()->layoutState();
if (layoutState->m_columnInfo)
layoutState->m_columnInfo->updateMinimumColumnHeight(childLogicalHeight);
diff --git a/Source/WebCore/rendering/RenderBlock.h b/Source/WebCore/rendering/RenderBlock.h
index 2ccf0aa25..8996da5ef 100644
--- a/Source/WebCore/rendering/RenderBlock.h
+++ b/Source/WebCore/rendering/RenderBlock.h
@@ -122,8 +122,8 @@ public:
void markPositionedObjectsForLayout();
virtual void markForPaginationRelayoutIfNeeded();
- bool containsFloats() { return m_floatingObjects && !m_floatingObjects->set().isEmpty(); }
- bool containsFloat(RenderBox*);
+ bool containsFloats() const { return m_floatingObjects && !m_floatingObjects->set().isEmpty(); }
+ bool containsFloat(RenderBox*) const;
// Versions that can compute line offsets with the region and page offset passed in. Used for speed to avoid having to
// compute the region all over again when you already know it.
@@ -145,6 +145,11 @@ public:
return style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, firstLine, region, offsetFromLogicalTopOfFirstPage)
: logicalWidth() - logicalRightOffsetForLine(position, firstLine, region, offsetFromLogicalTopOfFirstPage);
}
+ LayoutUnit endOffsetForLine(LayoutUnit position, bool firstLine, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage) const
+ {
+ return !style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, firstLine, region, offsetFromLogicalTopOfFirstPage)
+ : logicalWidth() - logicalRightOffsetForLine(position, firstLine, region, offsetFromLogicalTopOfFirstPage);
+ }
LayoutUnit availableLogicalWidthForLine(LayoutUnit position, bool firstLine) const
{
@@ -163,6 +168,11 @@ public:
return style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, firstLine)
: logicalWidth() - logicalRightOffsetForLine(position, firstLine);
}
+ LayoutUnit endOffsetForLine(LayoutUnit position, bool firstLine) const
+ {
+ return !style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, firstLine)
+ : logicalWidth() - logicalRightOffsetForLine(position, firstLine);
+ }
// FIXME: The implementation for these functions will change once we move to subpixel layout. See bug 60318.
int pixelSnappedLogicalRightOffsetForLine(LayoutUnit position, bool firstLine) const
@@ -242,12 +252,12 @@ public:
unsigned columnCount(ColumnInfo*) const;
LayoutRect columnRectAt(ColumnInfo*, unsigned) const;
- LayoutUnit paginationStrut() const { return m_rareData ? m_rareData->m_paginationStrut : 0; }
+ LayoutUnit paginationStrut() const { return m_rareData ? m_rareData->m_paginationStrut : zeroLayoutUnit; }
void setPaginationStrut(LayoutUnit);
// The page logical offset is the object's offset from the top of the page in the page progression
// direction (so an x-offset in vertical text and a y-offset for horizontal text).
- int pageLogicalOffset() const { return m_rareData ? m_rareData->m_pageLogicalOffset : 0; }
+ LayoutUnit pageLogicalOffset() const { return m_rareData ? m_rareData->m_pageLogicalOffset : zeroLayoutUnit; }
void setPageLogicalOffset(int);
RootInlineBox* lineGridBox() const { return m_rareData ? m_rareData->m_lineGridBox : 0; }
@@ -326,6 +336,11 @@ public:
return style()->isLeftToRightDirection() ? logicalLeftOffsetForContent(region, offsetFromLogicalTopOfFirstPage)
: logicalWidth() - logicalRightOffsetForContent(region, offsetFromLogicalTopOfFirstPage);
}
+ LayoutUnit endOffsetForContent(RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage) const
+ {
+ return !style()->isLeftToRightDirection() ? logicalLeftOffsetForContent(region, offsetFromLogicalTopOfFirstPage)
+ : logicalWidth() - logicalRightOffsetForContent(region, offsetFromLogicalTopOfFirstPage);
+ }
LayoutUnit logicalLeftOffsetForContent(LayoutUnit blockOffset) const
{
return logicalLeftOffsetForContent(regionAtBlockOffset(blockOffset), offsetFromLogicalTopOfFirstPage());
@@ -342,9 +357,14 @@ public:
{
return startOffsetForContent(regionAtBlockOffset(blockOffset), offsetFromLogicalTopOfFirstPage());
}
+ LayoutUnit endOffsetForContent(LayoutUnit blockOffset) const
+ {
+ return endOffsetForContent(regionAtBlockOffset(blockOffset), offsetFromLogicalTopOfFirstPage());
+ }
LayoutUnit logicalLeftOffsetForContent() const { return isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop(); }
LayoutUnit logicalRightOffsetForContent() const { return logicalLeftOffsetForContent() + availableLogicalWidth(); }
LayoutUnit startOffsetForContent() const { return style()->isLeftToRightDirection() ? logicalLeftOffsetForContent() : logicalWidth() - logicalRightOffsetForContent(); }
+ LayoutUnit endOffsetForContent() const { return !style()->isLeftToRightDirection() ? logicalLeftOffsetForContent() : logicalWidth() - logicalRightOffsetForContent(); }
void setStaticInlinePositionForChild(RenderBox*, LayoutUnit blockOffset, LayoutUnit inlinePosition);
@@ -365,23 +385,23 @@ protected:
{
return moveChildTo(to, child, 0, fullRemoveInsert);
}
- void moveChildTo(RenderBlock* to, RenderObject* child, RenderObject* beforeChild, bool fullRemoveInsert = false);
- void moveAllChildrenTo(RenderBlock* to, bool fullRemoveInsert = false)
+ void moveChildTo(RenderBlock* toBlock, RenderObject* child, RenderObject* beforeChild, bool fullRemoveInsert = false);
+ void moveAllChildrenTo(RenderBlock* toBlock, bool fullRemoveInsert = false)
{
- return moveAllChildrenTo(to, 0, fullRemoveInsert);
+ return moveAllChildrenTo(toBlock, 0, fullRemoveInsert);
}
- void moveAllChildrenTo(RenderBlock* to, RenderObject* beforeChild, bool fullRemoveInsert = false)
+ void moveAllChildrenTo(RenderBlock* toBlock, RenderObject* beforeChild, bool fullRemoveInsert = false)
{
- return moveChildrenTo(to, firstChild(), 0, beforeChild, fullRemoveInsert);
+ return moveChildrenTo(toBlock, firstChild(), 0, beforeChild, fullRemoveInsert);
}
// Move all of the kids from |startChild| up to but excluding |endChild|. 0 can be passed as the endChild to denote
// that all the kids from |startChild| onwards should be added.
- void moveChildrenTo(RenderBlock* to, RenderObject* startChild, RenderObject* endChild, bool fullRemoveInsert = false)
+ void moveChildrenTo(RenderBlock* toBlock, RenderObject* startChild, RenderObject* endChild, bool fullRemoveInsert = false)
{
- return moveChildrenTo(to, startChild, endChild, 0, fullRemoveInsert);
+ return moveChildrenTo(toBlock, startChild, endChild, 0, fullRemoveInsert);
}
- void moveChildrenTo(RenderBlock* to, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert = false);
-
+ void moveChildrenTo(RenderBlock* toBlock, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert = false);
+
LayoutUnit maxPositiveMarginBefore() const { return m_rareData ? m_rareData->m_margins.positiveMarginBefore() : RenderBlockRareData::positiveMarginBeforeDefault(this); }
LayoutUnit maxNegativeMarginBefore() const { return m_rareData ? m_rareData->m_margins.negativeMarginBefore() : RenderBlockRareData::negativeMarginBeforeDefault(this); }
LayoutUnit maxPositiveMarginAfter() const { return m_rareData ? m_rareData->m_margins.positiveMarginAfter() : RenderBlockRareData::positiveMarginAfterDefault(this); }
@@ -822,6 +842,7 @@ private:
void updateScrollInfoAfterLayout();
RenderObject* splitAnonymousBlocksAroundChild(RenderObject* beforeChild);
+ RenderObject* splitTablePartsAroundChild(RenderObject* beforeChild);
void splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock, RenderBlock* middleBlock,
RenderObject* beforeChild, RenderBoxModelObject* oldCont);
void splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
diff --git a/Source/WebCore/rendering/RenderBlockLineLayout.cpp b/Source/WebCore/rendering/RenderBlockLineLayout.cpp
index 406930fc1..47b632464 100755
--- a/Source/WebCore/rendering/RenderBlockLineLayout.cpp
+++ b/Source/WebCore/rendering/RenderBlockLineLayout.cpp
@@ -491,6 +491,9 @@ RootInlineBox* RenderBlock::constructLine(BidiRunList<BidiRun>& bidiRuns, const
if (runCount == 2 && !r->m_object->isListMarker())
isOnlyRun = (!style()->isLeftToRightDirection() ? bidiRuns.lastRun() : bidiRuns.firstRun())->m_object->isListMarker();
+ if (lineInfo.isEmpty())
+ continue;
+
InlineBox* box = createInlineBoxForRenderer(r->m_object, false, isOnlyRun);
r->m_box = box;
@@ -1093,8 +1096,8 @@ public:
void updateRepaintRangeFromBox(RootInlineBox* box, LayoutUnit paginationDelta = 0)
{
m_usesRepaintBounds = true;
- m_repaintLogicalTop = min(m_repaintLogicalTop, box->logicalTopVisualOverflow() + min(paginationDelta, 0));
- m_repaintLogicalBottom = max(m_repaintLogicalBottom, box->logicalBottomVisualOverflow() + max(paginationDelta, 0));
+ m_repaintLogicalTop = min(m_repaintLogicalTop, box->logicalTopVisualOverflow() + min(paginationDelta, zeroLayoutUnit));
+ m_repaintLogicalBottom = max(m_repaintLogicalBottom, box->logicalBottomVisualOverflow() + max(paginationDelta, zeroLayoutUnit));
}
bool endLineMatched() const { return m_endLineMatched; }
@@ -1459,7 +1462,7 @@ void RenderBlock::layoutInlineChildren(bool relayoutChildren, LayoutUnit& repain
LineLayoutState layoutState(isFullLayout, repaintLogicalTop, repaintLogicalBottom);
if (isFullLayout)
- lineBoxes()->deleteLineBoxes(renderArena());
+ deleteLineBoxTree();
// Text truncation only kicks in if your overflow isn't visible and your text-overflow-mode isn't
// clip.
@@ -1831,14 +1834,22 @@ static inline bool shouldCollapseWhiteSpace(const RenderStyle* style, const Line
|| (whitespacePosition == TrailingWhitespace && style->whiteSpace() == PRE_WRAP && (!lineInfo.isEmpty() || !lineInfo.previousLineBrokeCleanly()));
}
-static bool inlineFlowRequiresLineBox(RenderInline* flow, const LineInfo& lineInfo)
+static bool requiresLineBoxForContent(RenderInline* flow, const LineInfo& lineInfo)
+{
+ RenderObject* parent = flow->parent();
+ if (flow->document()->inNoQuirksMode()
+ && (flow->style(lineInfo.isFirstLine())->lineHeight() != parent->style(lineInfo.isFirstLine())->lineHeight()
+ || flow->style()->verticalAlign() != parent->style()->verticalAlign()
+ || !parent->style()->font().fontMetrics().hasIdenticalAscentDescentAndLineGap(flow->style()->font().fontMetrics())))
+ return true;
+ return false;
+}
+
+static bool alwaysRequiresLineBox(RenderInline* flow)
{
// FIXME: Right now, we only allow line boxes for inlines that are truly empty.
// We need to fix this, though, because at the very least, inlines containing only
// ignorable whitespace should should also have line boxes.
- if (!flow->document()->inQuirksMode() && flow->style(lineInfo.isFirstLine())->lineHeight() != flow->parent()->style(lineInfo.isFirstLine())->lineHeight())
- return true;
-
return !flow->firstChild() && flow->hasInlineDirectionBordersPaddingOrMargin();
}
@@ -1847,7 +1858,7 @@ static bool requiresLineBox(const InlineIterator& it, const LineInfo& lineInfo =
if (it.m_obj->isFloatingOrPositioned())
return false;
- if (it.m_obj->isRenderInline() && !inlineFlowRequiresLineBox(toRenderInline(it.m_obj), lineInfo))
+ if (it.m_obj->isRenderInline() && !alwaysRequiresLineBox(toRenderInline(it.m_obj)) && !requiresLineBoxForContent(toRenderInline(it.m_obj), lineInfo))
return false;
if (!shouldCollapseWhiteSpace(it.m_obj->style(), lineInfo, whitespacePosition) || it.m_obj->isBR())
@@ -2235,8 +2246,12 @@ InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resol
// to make sure that we stop to include this object and then start ignoring spaces again.
// If this object is at the start of the line, we need to behave like list markers and
// start ignoring spaces.
- if (inlineFlowRequiresLineBox(flowBox, lineInfo)) {
- lineInfo.setEmpty(false, m_block, &width);
+ bool requiresLineBox = alwaysRequiresLineBox(flowBox);
+ if (requiresLineBox || requiresLineBoxForContent(flowBox, lineInfo)) {
+ // An empty inline that only has line-height, vertical-align or font-metrics will only get a
+ // line box to affect the height of the line if the rest of the line is not empty.
+ if (requiresLineBox)
+ lineInfo.setEmpty(false, m_block, &width);
if (ignoringSpaces) {
trailingObjects.clear();
addMidpoint(lineMidpointState, InlineIterator(0, current.m_obj, 0)); // Stop ignoring spaces.
@@ -2354,7 +2369,7 @@ InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resol
midWordBreak = width.committedWidth() + wrapW + charWidth > width.availableWidth();
}
- if (lineBreakIteratorInfo.first != t) {
+ if ((lineBreakIteratorInfo.first != t) || (lineBreakIteratorInfo.second.string() != t->characters())) {
lineBreakIteratorInfo.first = t;
lineBreakIteratorInfo.second.reset(t->characters(), t->textLength(), style->locale());
}
@@ -2651,7 +2666,7 @@ InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resol
void RenderBlock::addOverflowFromInlineChildren()
{
- LayoutUnit endPadding = hasOverflowClip() ? paddingEnd() : 0;
+ LayoutUnit endPadding = hasOverflowClip() ? paddingEnd() : zeroLayoutUnit;
// FIXME: Need to find another way to do this, since scrollbars could show when we don't want them to.
if (hasOverflowClip() && !endPadding && node() && node()->rendererIsEditable() && node() == node()->rootEditableElement() && style()->isLeftToRightDirection())
endPadding = 1;
diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp
index f3ca0b1d1..d21c2405d 100644
--- a/Source/WebCore/rendering/RenderBox.cpp
+++ b/Source/WebCore/rendering/RenderBox.cpp
@@ -746,6 +746,13 @@ bool RenderBox::needsPreferredWidthsRecalculation() const
return style()->paddingStart().isPercent() || style()->paddingEnd().isPercent();
}
+IntSize RenderBox::scrolledContentOffset() const
+{
+ ASSERT(hasOverflowClip());
+ ASSERT(hasLayer());
+ return layer()->scrolledContentOffset();
+}
+
LayoutUnit RenderBox::minPreferredLogicalWidth() const
{
if (preferredLogicalWidthsDirty())
@@ -917,11 +924,12 @@ void RenderBox::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint& pai
// balloon layout is an example of this).
borderFitAdjust(paintRect);
+ BackgroundBleedAvoidance bleedAvoidance = determineBackgroundBleedAvoidance(paintInfo.context);
+
// FIXME: Should eventually give the theme control over whether the box shadow should paint, since controls could have
// custom shadows of their own.
- paintBoxShadow(paintInfo, paintRect, style(), Normal);
-
- BackgroundBleedAvoidance bleedAvoidance = determineBackgroundBleedAvoidance(paintInfo.context);
+ if (!boxShadowShouldBeAppliedToBackground(bleedAvoidance))
+ paintBoxShadow(paintInfo, paintRect, style(), Normal);
GraphicsContextStateSaver stateSaver(*paintInfo.context, false);
if (bleedAvoidance == BackgroundBleedUseTransparencyLayer) {
@@ -941,12 +949,12 @@ void RenderBox::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint& pai
paintBackground(paintInfo, paintRect, bleedAvoidance);
if (style()->hasAppearance())
- theme()->paintDecorations(this, paintInfo, paintRect);
+ theme()->paintDecorations(this, paintInfo, pixelSnappedIntRect(paintRect));
}
paintBoxShadow(paintInfo, paintRect, style(), Inset);
// The theme will tell us whether or not we should also paint the CSS border.
- if ((!style()->hasAppearance() || (!themePainted && theme()->paintBorderOnly(this, paintInfo, paintRect))) && style()->hasBorder())
+ if ((!style()->hasAppearance() || (!themePainted && theme()->paintBorderOnly(this, paintInfo, pixelSnappedIntRect(paintRect)))) && style()->hasBorder())
paintBorder(paintInfo, paintRect, style(), bleedAvoidance);
if (bleedAvoidance == BackgroundBleedUseTransparencyLayer)
@@ -1186,7 +1194,7 @@ bool RenderBox::pushContentsClip(PaintInfo& paintInfo, const LayoutPoint& accumu
paintObject(paintInfo, accumulatedOffset);
paintInfo.phase = PaintPhaseChildBlockBackgrounds;
}
- IntRect clipRect(isControlClip ? controlClipRect(accumulatedOffset) : overflowClipRect(accumulatedOffset, paintInfo.renderRegion));
+ IntRect clipRect = pixelSnappedIntRect(isControlClip ? controlClipRect(accumulatedOffset) : overflowClipRect(accumulatedOffset, paintInfo.renderRegion));
paintInfo.context->save();
if (style()->hasBorderRadius())
paintInfo.context->addRoundedRectClip(style()->getRoundedInnerBorderFor(LayoutRect(accumulatedOffset, size())));
@@ -1251,11 +1259,50 @@ LayoutRect RenderBox::clipRect(const LayoutPoint& location, RenderRegion* region
return clipRect;
}
+LayoutUnit RenderBox::shrinkLogicalWidthToAvoidFloats(LayoutUnit childMarginStart, LayoutUnit childMarginEnd, const RenderBlock* cb, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage)
+{
+ RenderRegion* containingBlockRegion = 0;
+ LayoutUnit logicalTopPosition = logicalTop();
+ LayoutUnit adjustedPageOffsetForContainingBlock = offsetFromLogicalTopOfFirstPage - logicalTop();
+ if (region) {
+ LayoutUnit offsetFromLogicalTopOfRegion = region ? region->offsetFromLogicalTopOfFirstPage() - offsetFromLogicalTopOfFirstPage : 0;
+ logicalTopPosition = max(logicalTopPosition, logicalTopPosition + offsetFromLogicalTopOfRegion);
+ containingBlockRegion = cb->clampToStartAndEndRegions(region);
+ }
+
+ LayoutUnit result = cb->availableLogicalWidthForLine(logicalTopPosition, false, containingBlockRegion, adjustedPageOffsetForContainingBlock) - childMarginStart - childMarginEnd;
+
+ // We need to see if margins on either the start side or the end side can contain the floats in question. If they can,
+ // then just using the line width is inaccurate. In the case where a float completely fits, we don't need to use the line
+ // offset at all, but can instead push all the way to the content edge of the containing block. In the case where the float
+ // doesn't fit, we can use the line offset, but we need to grow it by the margin to reflect the fact that the margin was
+ // "consumed" by the float. Negative margins aren't consumed by the float, and so we ignore them.
+ if (childMarginStart > 0) {
+ LayoutUnit startContentSide = cb->startOffsetForContent(containingBlockRegion, adjustedPageOffsetForContainingBlock);
+ LayoutUnit startContentSideWithMargin = startContentSide + childMarginStart;
+ LayoutUnit startOffset = cb->startOffsetForLine(logicalTopPosition, false, containingBlockRegion, adjustedPageOffsetForContainingBlock);
+ if (startOffset > startContentSideWithMargin)
+ result += childMarginStart;
+ else
+ result += startOffset - startContentSide;
+ }
+
+ if (childMarginEnd > 0) {
+ LayoutUnit endContentSide = cb->endOffsetForContent(containingBlockRegion, adjustedPageOffsetForContainingBlock);
+ LayoutUnit endContentSideWithMargin = endContentSide + childMarginEnd;
+ LayoutUnit endOffset = cb->endOffsetForLine(logicalTopPosition, false, containingBlockRegion, adjustedPageOffsetForContainingBlock);
+ if (endOffset > endContentSideWithMargin)
+ result += childMarginEnd;
+ else
+ result += endOffset - endContentSide;
+ }
+
+ return result;
+}
+
LayoutUnit RenderBox::containingBlockLogicalWidthForContent() const
{
RenderBlock* cb = containingBlock();
- if (shrinkToAvoidFloats() && !inRenderFlowThread())
- return cb->availableLogicalWidthForLine(logicalTop(), false);
return cb->availableLogicalWidth();
}
@@ -1266,10 +1313,6 @@ LayoutUnit RenderBox::containingBlockLogicalWidthForContentInRegion(RenderRegion
RenderBlock* cb = containingBlock();
RenderRegion* containingBlockRegion = cb->clampToStartAndEndRegions(region);
- if (shrinkToAvoidFloats()) {
- LayoutUnit offsetFromLogicalTopOfRegion = region->offsetFromLogicalTopOfFirstPage() - offsetFromLogicalTopOfFirstPage;
- return cb->availableLogicalWidthForLine(max(logicalTop(), logicalTop() + offsetFromLogicalTopOfRegion), false, containingBlockRegion, offsetFromLogicalTopOfFirstPage - logicalTop());
- }
LayoutUnit result = cb->availableLogicalWidth();
RenderBoxRegionInfo* boxInfo = cb->renderBoxRegionInfo(containingBlockRegion, offsetFromLogicalTopOfFirstPage - logicalTop());
if (!boxInfo)
@@ -1397,7 +1440,7 @@ LayoutSize RenderBox::offsetFromContainer(RenderObject* o, const LayoutPoint& po
}
if (o->hasOverflowClip())
- offset -= toRenderBox(o)->layer()->scrolledContentOffset();
+ offset -= toRenderBox(o)->scrolledContentOffset();
if (style()->position() == AbsolutePosition && o->isRelPositioned() && o->isRenderInline())
offset += toRenderInline(o)->relativePositionedInlineOffset(this);
@@ -1596,7 +1639,7 @@ void RenderBox::computeRectForRepaint(RenderBoxModelObject* repaintContainer, La
// 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());
@@ -1691,11 +1734,11 @@ void RenderBox::computeLogicalWidthInRegion(RenderRegion* region, LayoutUnit off
setLogicalWidth(logicalWidthLength.value() + borderAndPaddingLogicalWidth());
else {
// Calculate LogicalWidth
- setLogicalWidth(computeLogicalWidthUsing(LogicalWidth, containerWidthInInlineDirection));
+ setLogicalWidth(computeLogicalWidthInRegionUsing(LogicalWidth, containerWidthInInlineDirection, cb, region, offsetFromLogicalTopOfFirstPage));
// Calculate MaxLogicalWidth
if (!styleToUse->logicalMaxWidth().isUndefined()) {
- LayoutUnit maxLogicalWidth = computeLogicalWidthUsing(MaxLogicalWidth, containerWidthInInlineDirection);
+ LayoutUnit maxLogicalWidth = computeLogicalWidthInRegionUsing(MaxLogicalWidth, containerWidthInInlineDirection, cb, region, offsetFromLogicalTopOfFirstPage);
if (logicalWidth() > maxLogicalWidth) {
setLogicalWidth(maxLogicalWidth);
logicalWidthLength = styleToUse->logicalMaxWidth();
@@ -1703,7 +1746,7 @@ void RenderBox::computeLogicalWidthInRegion(RenderRegion* region, LayoutUnit off
}
// Calculate MinLogicalWidth
- LayoutUnit minLogicalWidth = computeLogicalWidthUsing(MinLogicalWidth, containerWidthInInlineDirection);
+ LayoutUnit minLogicalWidth = computeLogicalWidthInRegionUsing(MinLogicalWidth, containerWidthInInlineDirection, cb, region, offsetFromLogicalTopOfFirstPage);
if (logicalWidth() < minLogicalWidth) {
setLogicalWidth(minLogicalWidth);
logicalWidthLength = styleToUse->logicalMinWidth();
@@ -1728,7 +1771,8 @@ void RenderBox::computeLogicalWidthInRegion(RenderRegion* region, LayoutUnit off
cb->setMarginEndForChild(this, containerLogicalWidth - logicalWidth() - cb->marginStartForChild(this));
}
-LayoutUnit RenderBox::computeLogicalWidthUsing(LogicalWidthType widthType, LayoutUnit availableLogicalWidth)
+LayoutUnit RenderBox::computeLogicalWidthInRegionUsing(LogicalWidthType widthType, LayoutUnit availableLogicalWidth,
+ const RenderBlock* cb, RenderRegion* region, LayoutUnit offsetFromLogicalTopOfFirstPage)
{
LayoutUnit logicalWidthResult = logicalWidth();
RenderStyle* styleToUse = style();
@@ -1745,6 +1789,9 @@ LayoutUnit RenderBox::computeLogicalWidthUsing(LogicalWidthType widthType, Layou
LayoutUnit marginEnd = styleToUse->marginEnd().calcMinValue(availableLogicalWidth);
logicalWidthResult = availableLogicalWidth - marginStart - marginEnd;
+ if (shrinkToAvoidFloats() && cb->containsFloats())
+ logicalWidthResult = shrinkLogicalWidthToAvoidFloats(marginStart, marginEnd, cb, region, offsetFromLogicalTopOfFirstPage);
+
if (sizesToIntrinsicLogicalWidth(widthType)) {
logicalWidthResult = max(logicalWidthResult, minPreferredLogicalWidth());
logicalWidthResult = min(logicalWidthResult, maxPreferredLogicalWidth());
@@ -1997,7 +2044,6 @@ void RenderBox::computeLogicalHeight()
LayoutUnit heightResult;
if (checkMinMaxHeight) {
heightResult = computeLogicalHeightUsing(styleToUse->logicalHeight());
- // FIXME: Use < 0 or roughlyEquals when we move to float, see https://bugs.webkit.org/show_bug.cgi?id=66148
if (heightResult == -1)
heightResult = logicalHeight();
LayoutUnit minH = computeLogicalHeightUsing(styleToUse->logicalMinHeight()); // Leave as -1 if unset.
@@ -2056,7 +2102,6 @@ LayoutUnit RenderBox::computeLogicalHeightUsing(const Length& h)
logicalHeight = h.value();
else if (h.isPercent())
logicalHeight = computePercentageLogicalHeight(h);
- // FIXME: Use < 0 or roughlyEquals when we move to float, see https://bugs.webkit.org/show_bug.cgi?id=66148
if (logicalHeight != -1) {
logicalHeight = computeBorderBoxLogicalHeight(logicalHeight);
return logicalHeight;
@@ -2123,7 +2168,6 @@ LayoutUnit RenderBox::computePercentageLogicalHeight(const Length& height)
else if (cbstyle->logicalHeight().isPercent() && !isPositionedWithSpecifiedHeight) {
// We need to recur and compute the percentage height for our containing block.
result = cb->computePercentageLogicalHeight(cbstyle->logicalHeight());
- // FIXME: Use < 0 or roughlyEquals when we move to float, see https://bugs.webkit.org/show_bug.cgi?id=66148
if (result != -1)
result = cb->computeContentBoxLogicalHeight(result);
} else if (cb->isRenderView() || (cb->isBody() && document()->inQuirksMode()) || isPositionedWithSpecifiedHeight) {
@@ -2138,7 +2182,6 @@ LayoutUnit RenderBox::computePercentageLogicalHeight(const Length& height)
// always. Note we could only hit this case by recurring into computePercentageLogicalHeight on a positioned containing block.
result = cb->computeContentBoxLogicalHeight(cb->availableLogicalHeight());
- // FIXME: Use < 0 or roughlyEquals when we move to float, see https://bugs.webkit.org/show_bug.cgi?id=66148
if (result != -1) {
result = height.calcValue(result);
if (includeBorderPadding) {
@@ -3444,9 +3487,9 @@ VisiblePosition RenderBox::positionForPoint(const LayoutPoint& point)
RenderBox* renderer = toRenderBox(renderObject);
- LayoutUnit top = renderer->borderTop() + renderer->paddingTop() + (isTableRow() ? 0 : renderer->y());
+ LayoutUnit top = renderer->borderTop() + renderer->paddingTop() + (isTableRow() ? zeroLayoutUnit : renderer->y());
LayoutUnit bottom = top + renderer->contentHeight();
- LayoutUnit left = renderer->borderLeft() + renderer->paddingLeft() + (isTableRow() ? 0 : renderer->x());
+ LayoutUnit left = renderer->borderLeft() + renderer->paddingLeft() + (isTableRow() ? zeroLayoutUnit : renderer->x());
LayoutUnit right = left + renderer->contentWidth();
if (point.x() <= right && point.x() >= left && point.y() <= top && point.y() >= bottom) {
diff --git a/Source/WebCore/rendering/RenderBox.h b/Source/WebCore/rendering/RenderBox.h
index f9b852c54..31ec39a20 100644
--- a/Source/WebCore/rendering/RenderBox.h
+++ b/Source/WebCore/rendering/RenderBox.h
@@ -151,6 +151,7 @@ public:
// respectively are flipped when compared to their physical counterparts. For example minX is on the left in vertical-lr,
// but it is on the right in vertical-rl.
LayoutRect layoutOverflowRect() const { return m_overflow ? m_overflow->layoutOverflowRect() : clientBoxRect(); }
+ IntRect pixelSnappedLayoutOverflowRect() const { return pixelSnappedIntRect(layoutOverflowRect()); }
LayoutUnit minYLayoutOverflow() const { return m_overflow? m_overflow->minYLayoutOverflow() : borderTop(); }
LayoutUnit maxYLayoutOverflow() const { return m_overflow ? m_overflow->maxYLayoutOverflow() : borderTop() + clientHeight(); }
LayoutUnit minXLayoutOverflow() const { return m_overflow ? m_overflow->minXLayoutOverflow() : borderLeft(); }
@@ -160,9 +161,9 @@ public:
LayoutUnit logicalRightLayoutOverflow() const { return style()->isHorizontalWritingMode() ? maxXLayoutOverflow() : maxYLayoutOverflow(); }
virtual LayoutRect visualOverflowRect() const { return m_overflow ? m_overflow->visualOverflowRect() : borderBoxRect(); }
- LayoutUnit minYVisualOverflow() const { return m_overflow? m_overflow->minYVisualOverflow() : 0; }
+ LayoutUnit minYVisualOverflow() const { return m_overflow? m_overflow->minYVisualOverflow() : zeroLayoutUnit; }
LayoutUnit maxYVisualOverflow() const { return m_overflow ? m_overflow->maxYVisualOverflow() : height(); }
- LayoutUnit minXVisualOverflow() const { return m_overflow ? m_overflow->minXVisualOverflow() : 0; }
+ LayoutUnit minXVisualOverflow() const { return m_overflow ? m_overflow->minXVisualOverflow() : zeroLayoutUnit; }
LayoutUnit maxXVisualOverflow() const { return m_overflow ? m_overflow->maxXVisualOverflow() : width(); }
LayoutUnit logicalLeftVisualOverflow() const { return style()->isHorizontalWritingMode() ? minXVisualOverflow() : minYVisualOverflow(); }
LayoutUnit logicalRightVisualOverflow() const { return style()->isHorizontalWritingMode() ? maxXVisualOverflow() : maxYVisualOverflow(); }
@@ -313,7 +314,7 @@ public:
virtual void computeLogicalHeight();
RenderBoxRegionInfo* renderBoxRegionInfo(RenderRegion*, LayoutUnit offsetFromLogicalTopOfFirstPage, RenderBoxRegionInfoFlags = CacheRenderBoxRegionInfo) const;
- void computeLogicalWidthInRegion(RenderRegion* = 0, LayoutUnit offsetFromLogicalTopOfFirstPage = 0);
+ void computeLogicalWidthInRegion(RenderRegion* = 0, LayoutUnit offsetFromLogicalTopOfFirstPage = zeroLayoutUnit);
bool stretchesToViewport() const
{
@@ -329,7 +330,9 @@ public:
bool sizesToIntrinsicLogicalWidth(LogicalWidthType) const;
virtual bool stretchesToMinIntrinsicLogicalWidth() const { return false; }
- LayoutUnit computeLogicalWidthUsing(LogicalWidthType, LayoutUnit availableLogicalWidth);
+ LayoutUnit shrinkLogicalWidthToAvoidFloats(LayoutUnit childMarginStart, LayoutUnit childMarginEnd, const RenderBlock* cb, RenderRegion*, LayoutUnit offsetFromLogicalTopOfFirstPage);
+
+ LayoutUnit computeLogicalWidthInRegionUsing(LogicalWidthType, LayoutUnit availableLogicalWidth, const RenderBlock* containingBlock, RenderRegion*, LayoutUnit offsetFromLogicalTopOfFirstPage);
LayoutUnit computeLogicalHeightUsing(const Length& height);
LayoutUnit computeReplacedLogicalWidthUsing(Length width) const;
LayoutUnit computeReplacedLogicalWidthRespectingMinMaxWidth(LayoutUnit logicalWidth, bool includeMaxWidth = true) const;
@@ -444,6 +447,8 @@ public:
virtual bool needsPreferredWidthsRecalculation() const;
virtual void computeIntrinsicRatioInformation(FloatSize& /* intrinsicSize */, double& /* intrinsicRatio */, bool& /* isPercentageIntrinsicSize */) const { }
+ IntSize scrolledContentOffset() const;
+
protected:
virtual void willBeDestroyed();
@@ -459,6 +464,8 @@ protected:
void paintMaskImages(const PaintInfo&, const LayoutRect&);
+ BackgroundBleedAvoidance determineBackgroundBleedAvoidance(GraphicsContext*) const;
+
#if PLATFORM(MAC)
void paintCustomHighlight(const LayoutPoint&, const AtomicString& type, bool behindText);
#endif
@@ -503,8 +510,6 @@ private:
// These include tables, positioned objects, floats and flexible boxes.
virtual void computePreferredLogicalWidths() { setPreferredLogicalWidthsDirty(false); }
- BackgroundBleedAvoidance determineBackgroundBleedAvoidance(GraphicsContext*) const;
-
private:
// The width/height of the contents + borders + padding. The x/y location is relative to our container (which is not always our parent).
LayoutRect m_frameRect;
diff --git a/Source/WebCore/rendering/RenderBoxModelObject.cpp b/Source/WebCore/rendering/RenderBoxModelObject.cpp
index 3aadee902..e3ab32180 100644
--- a/Source/WebCore/rendering/RenderBoxModelObject.cpp
+++ b/Source/WebCore/rendering/RenderBoxModelObject.cpp
@@ -168,8 +168,6 @@ bool ImageQualityController::shouldPaintAtLowQuality(GraphicsContext* context, R
const AffineTransform& currentTransform = context->getCTM();
bool contextIsScaled = !currentTransform.isIdentityOrTranslationOrFlipped();
- // FIXME: Change to use roughlyEquals when we move to float.
- // See https://bugs.webkit.org/show_bug.cgi?id=66148
if (!contextIsScaled && size == imageSize) {
// There is no scale in effect. If we had a scale in effect before, we can just remove this object from the list.
removeLayer(object, innerMap, layer);
@@ -192,8 +190,6 @@ bool ImageQualityController::shouldPaintAtLowQuality(GraphicsContext* context, R
// If this is the first time resizing this image, or its size is the
// same as the last resize, draw at high res, but record the paint
// size and set the timer.
- // FIXME: Change to use roughlyEquals when we move to float.
- // See https://bugs.webkit.org/show_bug.cgi?id=66148
if (isFirstResize || oldSize == size) {
restartTimer();
set(object, innerMap, layer, size);
@@ -362,7 +358,7 @@ void RenderBoxModelObject::styleDidChange(StyleDifference diff, const RenderStyl
updateBoxModelInfoFromStyle();
if (requiresLayer()) {
- if (!layer()) {
+ if (!layer() && layerCreationAllowedForSubtree()) {
if (s_wasFloating && isFloating())
setChildNeedsLayout(true);
m_layer = new (renderArena()) RenderLayer(this);
@@ -401,8 +397,26 @@ void RenderBoxModelObject::updateBoxModelInfoFromStyle()
setHorizontalWritingMode(styleToUse->isHorizontalWritingMode());
}
+enum RelPosAxis { RelPosX, RelPosY };
+
+static LayoutUnit accumulateRelativePositionOffsets(const RenderObject* child, RelPosAxis axis)
+{
+ if (!child->isAnonymousBlock() || !child->isRelPositioned())
+ return 0;
+ LayoutUnit offset = 0;
+ RenderObject* p = toRenderBlock(child)->inlineElementContinuation();
+ while (p && p->isRenderInline()) {
+ if (p->isRelPositioned())
+ offset += (axis == RelPosX) ? toRenderInline(p)->relativePositionOffsetX() : toRenderInline(p)->relativePositionOffsetY();
+ p = p->parent();
+ }
+ return offset;
+}
+
LayoutUnit RenderBoxModelObject::relativePositionOffsetX() const
{
+ LayoutUnit offset = accumulateRelativePositionOffsets(this, RelPosX);
+
// Objects that shrink to avoid floats normally use available line width when computing containing block width. However
// in the case of relative positioning using percentages, we can't do this. The offset should always be resolved using the
// available width of the containing block. Therefore we don't use containingBlockLogicalWidthForContent() here, but instead explicitly
@@ -411,19 +425,20 @@ LayoutUnit RenderBoxModelObject::relativePositionOffsetX() const
RenderBlock* cb = containingBlock();
if (!style()->right().isAuto() && !cb->style()->isLeftToRightDirection())
return -style()->right().calcValue(cb->availableWidth());
- return style()->left().calcValue(cb->availableWidth());
+ return offset + style()->left().calcValue(cb->availableWidth());
}
if (!style()->right().isAuto()) {
RenderBlock* cb = containingBlock();
- return -style()->right().calcValue(cb->availableWidth());
+ return offset + -style()->right().calcValue(cb->availableWidth());
}
- return 0;
+ return offset;
}
LayoutUnit RenderBoxModelObject::relativePositionOffsetY() const
{
+ LayoutUnit offset = accumulateRelativePositionOffsets(this, RelPosY);
+
RenderBlock* containingBlock = this->containingBlock();
-
// If the containing block of a relatively positioned element does not
// specify a height, a percentage top or bottom offset should be resolved as
// auto. An exception to this is if the containing block has the WinIE quirk
@@ -434,15 +449,15 @@ LayoutUnit RenderBoxModelObject::relativePositionOffsetY() const
&& (!containingBlock->style()->height().isAuto()
|| !style()->top().isPercent()
|| containingBlock->stretchesToViewport()))
- return style()->top().calcValue(containingBlock->availableHeight());
+ return offset + style()->top().calcValue(containingBlock->availableHeight());
if (!style()->bottom().isAuto()
&& (!containingBlock->style()->height().isAuto()
|| !style()->bottom().isPercent()
|| containingBlock->stretchesToViewport()))
- return -style()->bottom().calcValue(containingBlock->availableHeight());
+ return offset + -style()->bottom().calcValue(containingBlock->availableHeight());
- return 0;
+ return offset;
}
LayoutUnit RenderBoxModelObject::offsetLeft() const
@@ -453,7 +468,7 @@ LayoutUnit RenderBoxModelObject::offsetLeft() const
return 0;
RenderBoxModelObject* offsetPar = offsetParent();
- LayoutUnit xPos = (isBox() ? toRenderBox(this)->left() : 0);
+ LayoutUnit xPos = (isBox() ? toRenderBox(this)->left() : zeroLayoutUnit);
// If the offsetParent of the element is null, or is the HTML body element,
// return the distance between the canvas origin and the left border edge
@@ -487,7 +502,7 @@ LayoutUnit RenderBoxModelObject::offsetTop() const
return 0;
RenderBoxModelObject* offsetPar = offsetParent();
- LayoutUnit yPos = (isBox() ? toRenderBox(this)->top() : 0);
+ LayoutUnit yPos = (isBox() ? toRenderBox(this)->top() : zeroLayoutUnit);
// If the offsetParent of the element is null, or is the HTML body element,
// return the distance between the canvas origin and the top border edge
@@ -619,6 +634,19 @@ static LayoutRect backgroundRectAdjustedForBleedAvoidance(GraphicsContext* conte
return adjustedRect;
}
+static void applyBoxShadowForBackground(GraphicsContext* context, RenderStyle* style)
+{
+ const ShadowData* boxShadow = style->boxShadow();
+ while (boxShadow->style() != Normal)
+ boxShadow = boxShadow->next();
+
+ FloatSize shadowOffset(boxShadow->x(), boxShadow->y());
+ if (!boxShadow->isWebkitBoxShadow())
+ context->setShadow(shadowOffset, boxShadow->blur(), boxShadow->color(), style->colorSpace());
+ else
+ context->setLegacyShadow(shadowOffset, boxShadow->blur(), boxShadow->color(), style->colorSpace());
+}
+
void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, const Color& color, const FillLayer* bgLayer, const LayoutRect& rect,
BackgroundBleedAvoidance bleedAvoidance, InlineFlowBox* box, const LayoutSize& boxSize, CompositeOperator op, RenderObject* backgroundObject)
{
@@ -669,11 +697,16 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
if (!colorVisible)
return;
+ bool boxShadowShouldBeAppliedToBackground = this->boxShadowShouldBeAppliedToBackground(bleedAvoidance, box);
+ GraphicsContextStateSaver shadowStateSaver(*context, boxShadowShouldBeAppliedToBackground);
+ if (boxShadowShouldBeAppliedToBackground)
+ applyBoxShadowForBackground(context, style());
+
if (hasRoundedBorder && bleedAvoidance != BackgroundBleedUseTransparencyLayer) {
RoundedRect border = getBackgroundRoundedRect(backgroundRectAdjustedForBleedAvoidance(context, rect, bleedAvoidance), box, boxSize.width(), boxSize.height(), includeLeftEdge, includeRightEdge);
context->fillRoundedRect(border, bgColor, style()->colorSpace());
} else
- context->fillRect(rect, bgColor, style()->colorSpace());
+ context->fillRect(pixelSnappedIntRect(rect), bgColor, style()->colorSpace());
return;
}
@@ -685,49 +718,53 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
context->addRoundedRectClip(border);
}
- LayoutUnit bLeft = includeLeftEdge ? borderLeft() : 0;
- LayoutUnit bRight = includeRightEdge ? borderRight() : 0;
- LayoutUnit pLeft = includeLeftEdge ? paddingLeft() : 0;
- LayoutUnit pRight = includeRightEdge ? paddingRight() : 0;
+ LayoutUnit bLeft = includeLeftEdge ? borderLeft() : zeroLayoutUnit;
+ LayoutUnit bRight = includeRightEdge ? borderRight() : zeroLayoutUnit;
+ LayoutUnit pLeft = includeLeftEdge ? paddingLeft() : zeroLayoutUnit;
+ LayoutUnit pRight = includeRightEdge ? paddingRight() : zeroLayoutUnit;
GraphicsContextStateSaver clipWithScrollingStateSaver(*context, clippedWithLocalScrolling);
LayoutRect scrolledPaintRect = rect;
if (clippedWithLocalScrolling) {
// Clip to the overflow area.
- context->clip(toRenderBox(this)->overflowClipRect(rect.location(), paintInfo.renderRegion));
+ RenderBox* thisBox = toRenderBox(this);
+ context->clip(thisBox->overflowClipRect(rect.location(), paintInfo.renderRegion));
// Adjust the paint rect to reflect a scrolled content box with borders at the ends.
- LayoutSize offset = layer()->scrolledContentOffset();
+ IntSize offset = thisBox->scrolledContentOffset();
scrolledPaintRect.move(-offset);
scrolledPaintRect.setWidth(bLeft + layer()->scrollWidth() + bRight);
scrolledPaintRect.setHeight(borderTop() + layer()->scrollHeight() + borderBottom());
}
GraphicsContextStateSaver backgroundClipStateSaver(*context, false);
+ OwnPtr<ImageBuffer> maskImage;
+ IntRect maskRect;
+
if (bgLayer->clip() == PaddingFillBox || bgLayer->clip() == ContentFillBox) {
// Clip to the padding or content boxes as necessary.
bool includePadding = bgLayer->clip() == ContentFillBox;
- LayoutRect clipRect = LayoutRect(scrolledPaintRect.x() + bLeft + (includePadding ? pLeft : 0),
- scrolledPaintRect.y() + borderTop() + (includePadding ? paddingTop() : 0),
- scrolledPaintRect.width() - bLeft - bRight - (includePadding ? pLeft + pRight : 0),
- scrolledPaintRect.height() - borderTop() - borderBottom() - (includePadding ? paddingTop() + paddingBottom() : 0));
+ LayoutRect clipRect = LayoutRect(scrolledPaintRect.x() + bLeft + (includePadding ? pLeft : zeroLayoutUnit),
+ scrolledPaintRect.y() + borderTop() + (includePadding ? paddingTop() : zeroLayoutUnit),
+ scrolledPaintRect.width() - bLeft - bRight - (includePadding ? pLeft + pRight : zeroLayoutUnit),
+ scrolledPaintRect.height() - borderTop() - borderBottom() - (includePadding ? paddingTop() + paddingBottom() : zeroLayoutUnit));
backgroundClipStateSaver.save();
context->clip(clipRect);
} else if (bgLayer->clip() == TextFillBox) {
// We have to draw our text into a mask that can then be used to clip background drawing.
// First figure out how big the mask has to be. It should be no bigger than what we need
// to actually render, so we should intersect the dirty rect with the border box of the background.
- LayoutRect maskRect = rect;
+ maskRect = pixelSnappedIntRect(rect);
maskRect.intersect(paintInfo.rect);
-
+
// Now create the mask.
- OwnPtr<ImageBuffer> maskImage = context->createCompatibleBuffer(maskRect.size());
+ maskImage = context->createCompatibleBuffer(maskRect.size());
if (!maskImage)
return;
-
+
GraphicsContext* maskImageContext = maskImage->context();
maskImageContext->translate(-maskRect.x(), -maskRect.y());
-
+
// Now add the text to the clip. We do this by painting using a special paint phase that signals to
// InlineTextBoxes that they should just add their contents to the clip.
PaintInfo info(maskImageContext, maskRect, PaintPhaseTextClip, true, 0, paintInfo.renderRegion, 0);
@@ -738,12 +775,13 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
LayoutSize localOffset = isBox() ? toRenderBox(this)->locationOffset() : LayoutSize();
paint(info, scrolledPaintRect.location() - localOffset);
}
-
+
// The mask has been created. Now we just need to clip to it.
backgroundClipStateSaver.save();
- context->clipToImageBuffer(maskImage.get(), maskRect);
+ context->clip(maskRect);
+ context->beginTransparencyLayer(1);
}
-
+
// Only fill with a base color (e.g., white) if we're the root document, since iframes/frames with
// no background in the child document should show the parent's background.
bool isOpaqueRoot = false;
@@ -777,8 +815,11 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
// Paint the color first underneath all images.
if (!bgLayer->next()) {
- LayoutRect backgroundRect(scrolledPaintRect);
- backgroundRect.intersect(paintInfo.rect);
+ IntRect backgroundRect(pixelSnappedIntRect(scrolledPaintRect));
+ bool boxShadowShouldBeAppliedToBackground = this->boxShadowShouldBeAppliedToBackground(bleedAvoidance, box);
+ if (!boxShadowShouldBeAppliedToBackground)
+ backgroundRect.intersect(paintInfo.rect);
+
// If we have an alpha and we are painting the root element, go ahead and blend with the base background color.
Color baseColor;
bool shouldClearBackground = false;
@@ -788,6 +829,10 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
shouldClearBackground = true;
}
+ GraphicsContextStateSaver shadowStateSaver(*context, boxShadowShouldBeAppliedToBackground);
+ if (boxShadowShouldBeAppliedToBackground)
+ applyBoxShadowForBackground(context, style());
+
if (baseColor.alpha()) {
if (bgColor.alpha())
baseColor = baseColor.blend(bgColor);
@@ -814,6 +859,11 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
compositeOp, useLowQualityScaling);
}
}
+
+ if (bgLayer->clip() == TextFillBox) {
+ context->drawImageBuffer(maskImage.get(), ColorSpaceDeviceRGB, maskRect, CompositeDestinationIn);
+ context->endTransparencyLayer();
+ }
}
static inline LayoutUnit resolveWidthForRatio(LayoutUnit height, const FloatSize& intrinsicRatio)
@@ -1064,7 +1114,7 @@ void RenderBoxModelObject::calculateBackgroundImageGeometry(const FillLayer* fil
} else
positioningAreaSize = LayoutSize(paintRect.width() - left - right, paintRect.height() - top - bottom);
} else {
- geometry.setDestRect(viewRect());
+ geometry.setDestRect(pixelSnappedIntRect(viewRect()));
positioningAreaSize = geometry.destRect().size();
}
@@ -1404,6 +1454,14 @@ static inline bool includesEdge(BorderEdgeFlags flags, BoxSide side)
return flags & edgeFlagForSide(side);
}
+static inline bool includesAdjacentEdges(BorderEdgeFlags flags)
+{
+ return (flags & (TopBorderEdge | RightBorderEdge)) == (TopBorderEdge | RightBorderEdge)
+ || (flags & (RightBorderEdge | BottomBorderEdge)) == (RightBorderEdge | BottomBorderEdge)
+ || (flags & (BottomBorderEdge | LeftBorderEdge)) == (BottomBorderEdge | LeftBorderEdge)
+ || (flags & (LeftBorderEdge | TopBorderEdge)) == (LeftBorderEdge | TopBorderEdge);
+}
+
inline bool edgesShareColor(const BorderEdge& firstEdge, const BorderEdge& secondEdge)
{
return firstEdge.color == secondEdge.color;
@@ -1527,7 +1585,7 @@ static bool joinRequiresMitre(BoxSide side, BoxSide adjacentSide, const BorderEd
}
void RenderBoxModelObject::paintOneBorderSide(GraphicsContext* graphicsContext, const RenderStyle* style, const RoundedRect& outerBorder, const RoundedRect& innerBorder,
- const LayoutRect& sideRect, BoxSide side, BoxSide adjacentSide1, BoxSide adjacentSide2, const BorderEdge edges[], const Path* path,
+ const IntRect& sideRect, BoxSide side, BoxSide adjacentSide1, BoxSide adjacentSide2, const BorderEdge edges[], const Path* path,
BackgroundBleedAvoidance bleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias, const Color* overrideColor)
{
const BorderEdge& edgeToRender = edges[side];
@@ -1572,9 +1630,9 @@ void RenderBoxModelObject::paintOneBorderSide(GraphicsContext* graphicsContext,
}
}
-static LayoutRect calculateSideRect(const RoundedRect& outerBorder, const BorderEdge edges[], int side)
+static IntRect calculateSideRect(const RoundedRect& outerBorder, const BorderEdge edges[], int side)
{
- LayoutRect sideRect = outerBorder.rect();
+ IntRect sideRect = outerBorder.rect();
int width = edges[side].width;
if (side == BSTop)
@@ -1600,7 +1658,7 @@ void RenderBoxModelObject::paintBorderSides(GraphicsContext* graphicsContext, co
roundedPath.addRoundedRect(outerBorder);
if (edges[BSTop].shouldRender() && includesEdge(edgeSet, BSTop)) {
- LayoutRect sideRect = outerBorder.rect();
+ IntRect sideRect = outerBorder.rect();
sideRect.setHeight(edges[BSTop].width);
bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSTop].style) || borderWillArcInnerEdge(innerBorder.radii().topLeft(), innerBorder.radii().topRight()));
@@ -1608,7 +1666,7 @@ void RenderBoxModelObject::paintBorderSides(GraphicsContext* graphicsContext, co
}
if (edges[BSBottom].shouldRender() && includesEdge(edgeSet, BSBottom)) {
- LayoutRect sideRect = outerBorder.rect();
+ IntRect sideRect = outerBorder.rect();
sideRect.shiftYEdgeTo(sideRect.maxY() - edges[BSBottom].width);
bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSBottom].style) || borderWillArcInnerEdge(innerBorder.radii().bottomLeft(), innerBorder.radii().bottomRight()));
@@ -1616,7 +1674,7 @@ void RenderBoxModelObject::paintBorderSides(GraphicsContext* graphicsContext, co
}
if (edges[BSLeft].shouldRender() && includesEdge(edgeSet, BSLeft)) {
- LayoutRect sideRect = outerBorder.rect();
+ IntRect sideRect = outerBorder.rect();
sideRect.setWidth(edges[BSLeft].width);
bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSLeft].style) || borderWillArcInnerEdge(innerBorder.radii().bottomLeft(), innerBorder.radii().topLeft()));
@@ -1624,7 +1682,7 @@ void RenderBoxModelObject::paintBorderSides(GraphicsContext* graphicsContext, co
}
if (edges[BSRight].shouldRender() && includesEdge(edgeSet, BSRight)) {
- LayoutRect sideRect = outerBorder.rect();
+ IntRect sideRect = outerBorder.rect();
sideRect.shiftXEdgeTo(sideRect.maxX() - edges[BSRight].width);
bool usePath = renderRadii && (borderStyleHasInnerDetail(edges[BSRight].style) || borderWillArcInnerEdge(innerBorder.radii().bottomRight(), innerBorder.radii().topRight()));
@@ -1657,7 +1715,7 @@ void RenderBoxModelObject::paintTranslucentBorderSides(GraphicsContext* graphics
commonColorEdgeSet |= edgeFlagForSide(currSide);
}
- bool useTransparencyLayer = commonColor.hasAlpha();
+ bool useTransparencyLayer = includesAdjacentEdges(commonColorEdgeSet) && commonColor.hasAlpha();
if (useTransparencyLayer) {
graphicsContext->beginTransparencyLayer(static_cast<float>(commonColor.alpha()) / 255);
commonColor = Color(commonColor.red(), commonColor.green(), commonColor.blue());
@@ -1753,7 +1811,7 @@ void RenderBoxModelObject::paintBorder(const PaintInfo& info, const LayoutRect&
for (int i = BSTop; i <= BSLeft; ++i) {
const BorderEdge& currEdge = edges[i];
if (currEdge.shouldRender()) {
- LayoutRect sideRect = calculateSideRect(outerBorder, edges, i);
+ IntRect sideRect = calculateSideRect(outerBorder, edges, i);
path.addRect(sideRect);
}
}
@@ -1933,7 +1991,7 @@ void RenderBoxModelObject::drawBoxSideFromPath(GraphicsContext* graphicsContext,
graphicsContext->setStrokeStyle(NoStroke);
graphicsContext->setFillColor(color, style->colorSpace());
- graphicsContext->drawRect(borderRect);
+ graphicsContext->drawRect(pixelSnappedIntRect(borderRect));
}
#else
void RenderBoxModelObject::paintBorder(const PaintInfo& info, const IntRect& rect, const RenderStyle* style,
@@ -2375,9 +2433,9 @@ void RenderBoxModelObject::clipBorderSidePolygon(GraphicsContext* graphicsContex
graphicsContext->clipConvexPolygon(4, secondQuad, !secondEdgeMatches);
}
-static LayoutRect calculateSideRectIncludingInner(const RoundedRect& outerBorder, const BorderEdge edges[], BoxSide side)
+static IntRect calculateSideRectIncludingInner(const RoundedRect& outerBorder, const BorderEdge edges[], BoxSide side)
{
- LayoutRect sideRect = outerBorder.rect();
+ IntRect sideRect = outerBorder.rect();
int width;
switch (side) {
@@ -2556,6 +2614,53 @@ bool RenderBoxModelObject::borderObscuresBackground() const
return true;
}
+bool RenderBoxModelObject::boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance bleedAvoidance, InlineFlowBox* inlineFlowBox) const
+{
+ if (bleedAvoidance != BackgroundBleedNone)
+ return false;
+
+ if (style()->hasAppearance())
+ return false;
+
+ bool hasOneNormalBoxShadow = false;
+ for (const ShadowData* currentShadow = style()->boxShadow(); currentShadow; currentShadow = currentShadow->next()) {
+ if (currentShadow->style() != Normal)
+ continue;
+
+ if (hasOneNormalBoxShadow)
+ return false;
+ hasOneNormalBoxShadow = true;
+
+ if (currentShadow->spread())
+ return false;
+ }
+
+ if (!hasOneNormalBoxShadow)
+ return false;
+
+ Color backgroundColor = style()->visitedDependentColor(CSSPropertyBackgroundColor);
+ if (!backgroundColor.isValid() || backgroundColor.alpha() < 255)
+ return false;
+
+ const FillLayer* lastBackgroundLayer = style()->backgroundLayers();
+ for (const FillLayer* next = lastBackgroundLayer->next(); next; next = lastBackgroundLayer->next())
+ lastBackgroundLayer = next;
+
+ if (lastBackgroundLayer->clip() != BorderFillBox)
+ return false;
+
+ if (lastBackgroundLayer->image() && style()->hasBorderRadius())
+ return false;
+
+ if (inlineFlowBox && !inlineFlowBox->boxShadowCanBeAppliedToBackground(*lastBackgroundLayer))
+ return false;
+
+ if (hasOverflowClip() && lastBackgroundLayer->attachment() == LocalBackgroundAttachment)
+ return false;
+
+ return true;
+}
+
static inline LayoutRect areaCastingShadowInHole(const LayoutRect& holeRect, int shadowBlur, int shadowSpread, const LayoutSize& shadowOffset)
{
LayoutRect bounds(holeRect);
@@ -2634,7 +2739,7 @@ void RenderBoxModelObject::paintBoxShadow(const PaintInfo& info, const LayoutRec
if (!rectToClipOut.isEmpty())
context->clipOutRoundedRect(rectToClipOut);
- RoundedRect influenceRect(shadowRect, border.radii());
+ RoundedRect influenceRect(pixelSnappedIntRect(shadowRect), border.radii());
influenceRect.expandRadii(2 * shadowBlur + shadowSpread);
if (allCornersClippedOut(influenceRect, info.rect))
context->fillRect(fillRect.rect(), Color::black, s->colorSpace());
@@ -2658,7 +2763,7 @@ void RenderBoxModelObject::paintBoxShadow(const PaintInfo& info, const LayoutRec
}
if (!rectToClipOut.isEmpty())
- context->clipOut(rectToClipOut);
+ context->clipOut(pixelSnappedIntRect(rectToClipOut));
context->fillRect(fillRect.rect(), Color::black, s->colorSpace());
}
} else {
@@ -2693,7 +2798,7 @@ void RenderBoxModelObject::paintBoxShadow(const PaintInfo& info, const LayoutRec
Color fillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), 255);
LayoutRect outerRect = areaCastingShadowInHole(border.rect(), shadowBlur, shadowSpread, shadowOffset);
- RoundedRect roundedHole(holeRect, border.radii());
+ RoundedRect roundedHole(pixelSnappedIntRect(holeRect), border.radii());
GraphicsContextStateSaver stateSaver(*context);
if (hasBorderRadius) {
@@ -2713,7 +2818,7 @@ void RenderBoxModelObject::paintBoxShadow(const PaintInfo& info, const LayoutRec
else
context->setShadow(shadowOffset, shadowBlur, shadowColor, s->colorSpace());
- context->fillRectWithRoundedHole(outerRect, roundedHole, fillColor, s->colorSpace());
+ context->fillRectWithRoundedHole(pixelSnappedIntRect(outerRect), roundedHole, fillColor, s->colorSpace());
}
}
}
diff --git a/Source/WebCore/rendering/RenderBoxModelObject.h b/Source/WebCore/rendering/RenderBoxModelObject.h
index 027b1fb89..11e97c3fd 100644
--- a/Source/WebCore/rendering/RenderBoxModelObject.h
+++ b/Source/WebCore/rendering/RenderBoxModelObject.h
@@ -127,6 +127,8 @@ public:
void paintBoxShadow(const PaintInfo&, const LayoutRect&, const RenderStyle*, ShadowStyle, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true);
void paintFillLayerExtended(const PaintInfo&, const Color&, const FillLayer*, const LayoutRect&, BackgroundBleedAvoidance, InlineFlowBox* = 0, const LayoutSize& = LayoutSize(), CompositeOperator = CompositeSourceOver, RenderObject* backgroundObject = 0);
+ virtual bool boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance, InlineFlowBox* = 0) const;
+
// Overridden by subclasses to determine line height and baseline position.
virtual LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const = 0;
virtual LayoutUnit baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const = 0;
@@ -218,7 +220,7 @@ private:
BoxSide, bool firstEdgeMatches, bool secondEdgeMatches);
void clipBorderSideForComplexInnerPath(GraphicsContext*, const RoundedRect&, const RoundedRect&, BoxSide, const class BorderEdge[]);
void paintOneBorderSide(GraphicsContext*, const RenderStyle*, const RoundedRect& outerBorder, const RoundedRect& innerBorder,
- const LayoutRect& sideRect, BoxSide, BoxSide adjacentSide1, BoxSide adjacentSide2, const class BorderEdge[],
+ const IntRect& sideRect, BoxSide, BoxSide adjacentSide1, BoxSide adjacentSide2, const class BorderEdge[],
const Path*, BackgroundBleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias, const Color* overrideColor = 0);
void paintTranslucentBorderSides(GraphicsContext*, const RenderStyle*, const RoundedRect& outerBorder, const RoundedRect& innerBorder,
const class BorderEdge[], BackgroundBleedAvoidance, bool includeLogicalLeftEdge, bool includeLogicalRightEdge, bool antialias = false);
diff --git a/Source/WebCore/rendering/RenderButton.cpp b/Source/WebCore/rendering/RenderButton.cpp
index e6d1920fe..dd23130a6 100644
--- a/Source/WebCore/rendering/RenderButton.cpp
+++ b/Source/WebCore/rendering/RenderButton.cpp
@@ -118,14 +118,6 @@ void RenderButton::updateFromElement()
}
}
-bool RenderButton::canHaveChildren() const
-{
- // Input elements can't have children, but button elements can. We'll
- // write the code assuming any other button types that might emerge in the future
- // can also have children.
- return !node()->hasTagName(inputTag);
-}
-
void RenderButton::setText(const String& str)
{
if (str.isEmpty()) {
@@ -157,6 +149,11 @@ void RenderButton::updateBeforeAfterContent(PseudoId type)
children()->updateBeforeAfterContent(this, type);
}
+RenderText* RenderButton::buttonText() const
+{
+ return m_buttonText;
+}
+
LayoutRect RenderButton::controlClipRect(const LayoutPoint& additionalOffset) const
{
// Clip to the padding box to at least give content the extra padding space.
diff --git a/Source/WebCore/rendering/RenderButton.h b/Source/WebCore/rendering/RenderButton.h
index 24cecd2f2..c851abc7d 100644
--- a/Source/WebCore/rendering/RenderButton.h
+++ b/Source/WebCore/rendering/RenderButton.h
@@ -50,14 +50,13 @@ public:
virtual void updateBeforeAfterContent(PseudoId);
+ virtual RenderText* buttonText() const OVERRIDE;
virtual bool hasControlClip() const { return true; }
virtual LayoutRect controlClipRect(const LayoutPoint&) const;
void setText(const String&);
String text() const;
- virtual bool canHaveChildren() const;
-
private:
virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
diff --git a/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.h b/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.h
index 417ebac75..101bedbe3 100644
--- a/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.h
+++ b/Source/WebCore/rendering/RenderDeprecatedFlexibleBox.h
@@ -49,6 +49,7 @@ public:
virtual bool isDeprecatedFlexibleBox() const { return true; }
virtual bool isFlexingChildren() const { return m_flexingChildren; }
virtual bool isStretchingChildren() const { return m_stretchingChildren; }
+ virtual RenderText* buttonText() const { return 0; }
void placeChild(RenderBox* child, const LayoutPoint& location);
diff --git a/Source/WebCore/rendering/RenderDetailsMarker.cpp b/Source/WebCore/rendering/RenderDetailsMarker.cpp
index 0b1de6973..c1468b543 100644
--- a/Source/WebCore/rendering/RenderDetailsMarker.cpp
+++ b/Source/WebCore/rendering/RenderDetailsMarker.cpp
@@ -132,7 +132,7 @@ void RenderDetailsMarker::paint(PaintInfo& paintInfo, const LayoutPoint& paintOf
overflowRect.moveBy(boxOrigin);
overflowRect.inflate(maximalOutlineSize(paintInfo.phase));
- if (!paintInfo.rect.intersects(overflowRect))
+ if (!paintInfo.rect.intersects(pixelSnappedIntRect(overflowRect)))
return;
const Color color(style()->visitedDependentColor(CSSPropertyColor));
diff --git a/Source/WebCore/rendering/RenderEmbeddedObject.cpp b/Source/WebCore/rendering/RenderEmbeddedObject.cpp
index 0140c1ed6..bdafd62d5 100644
--- a/Source/WebCore/rendering/RenderEmbeddedObject.cpp
+++ b/Source/WebCore/rendering/RenderEmbeddedObject.cpp
@@ -190,7 +190,7 @@ void RenderEmbeddedObject::paintReplaced(PaintInfo& paintInfo, const LayoutPoint
bool RenderEmbeddedObject::getReplacementTextGeometry(const LayoutPoint& accumulatedOffset, FloatRect& contentRect, Path& path, FloatRect& replacementTextRect, Font& font, TextRun& run, float& textWidth) const
{
contentRect = contentBoxRect();
- contentRect.moveBy(accumulatedOffset);
+ contentRect.moveBy(roundedIntPoint(accumulatedOffset));
FontDescription fontDescription;
RenderTheme::defaultTheme()->systemFont(CSSValueWebkitSmallControl, fontDescription);
diff --git a/Source/WebCore/rendering/RenderFieldset.cpp b/Source/WebCore/rendering/RenderFieldset.cpp
index 3a70866e2..1d18bb9df 100644
--- a/Source/WebCore/rendering/RenderFieldset.cpp
+++ b/Source/WebCore/rendering/RenderFieldset.cpp
@@ -132,16 +132,17 @@ void RenderFieldset::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint
// cases the legend is embedded in the right and bottom borders respectively.
// https://bugs.webkit.org/show_bug.cgi?id=47236
if (style()->isHorizontalWritingMode()) {
- LayoutUnit yOff = (legend->y() > 0) ? 0 : (legend->height() - borderTop()) / 2;
+ LayoutUnit yOff = (legend->y() > 0) ? zeroLayoutUnit : (legend->height() - borderTop()) / 2;
paintRect.setHeight(paintRect.height() - yOff);
paintRect.setY(paintRect.y() + yOff);
} else {
- LayoutUnit xOff = (legend->x() > 0) ? 0 : (legend->width() - borderLeft()) / 2;
+ LayoutUnit xOff = (legend->x() > 0) ? zeroLayoutUnit : (legend->width() - borderLeft()) / 2;
paintRect.setWidth(paintRect.width() - xOff);
paintRect.setX(paintRect.x() + xOff);
}
-
- paintBoxShadow(paintInfo, paintRect, style(), Normal);
+
+ if (!boxShadowShouldBeAppliedToBackground(determineBackgroundBleedAvoidance(paintInfo.context)))
+ paintBoxShadow(paintInfo, paintRect, style(), Normal);
paintFillLayers(paintInfo, style()->visitedDependentColor(CSSPropertyBackgroundColor), style()->backgroundLayers(), paintRect);
paintBoxShadow(paintInfo, paintRect, style(), Inset);
diff --git a/Source/WebCore/rendering/RenderFileUploadControl.cpp b/Source/WebCore/rendering/RenderFileUploadControl.cpp
index a1ae15b5c..a927f3fae 100644
--- a/Source/WebCore/rendering/RenderFileUploadControl.cpp
+++ b/Source/WebCore/rendering/RenderFileUploadControl.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2012 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -32,6 +32,7 @@
#include "RenderText.h"
#include "RenderTheme.h"
#include "ShadowRoot.h"
+#include "ShadowRootList.h"
#include "TextRun.h"
#include "VisiblePosition.h"
#include <math.h>
@@ -85,7 +86,7 @@ void RenderFileUploadControl::updateFromElement()
static int nodeWidth(Node* node)
{
- return node ? node->renderBox()->width() : 0;
+ return node ? node->renderBox()->width() : zeroLayoutUnit;
}
int RenderFileUploadControl::maxFilenameWidth() const
@@ -177,10 +178,15 @@ void RenderFileUploadControl::computePreferredLogicalWidths()
else {
// Figure out how big the filename space needs to be for a given number of characters
// (using "0" as the nominal character).
- const UChar ch = '0';
- const String str = String(&ch, 1);
- float charWidth = font.width(constructTextRun(this, font, str, style, TextRun::AllowTrailingExpansion));
- m_maxPreferredLogicalWidth = (int)ceilf(charWidth * defaultWidthNumChars);
+ const UChar character = '0';
+ const String characterAsString = String(&character, 1);
+ float minDefaultLabelWidth = defaultWidthNumChars * font.width(constructTextRun(this, font, characterAsString, style, TextRun::AllowTrailingExpansion));
+
+ const String label = theme()->fileListDefaultLabel(node()->toInputElement()->multiple());
+ float defaultLabelWidth = font.width(constructTextRun(this, font, label, style, TextRun::AllowTrailingExpansion));
+ if (HTMLInputElement* button = uploadButton())
+ defaultLabelWidth += button->renderer()->maxPreferredLogicalWidth() + afterButtonSpacing;
+ m_maxPreferredLogicalWidth = static_cast<int>(ceilf(max(minDefaultLabelWidth, defaultLabelWidth)));
}
if (style->minWidth().isFixed() && style->minWidth().value() > 0) {
@@ -212,9 +218,9 @@ HTMLInputElement* RenderFileUploadControl::uploadButton() const
{
HTMLInputElement* input = static_cast<HTMLInputElement*>(node());
- ASSERT(input->shadowRoot());
+ ASSERT(input->hasShadowRoot());
- Node* buttonNode = input->shadowRoot()->firstChild();
+ Node* buttonNode = input->shadowRootList()->oldestShadowRoot()->firstChild();
return buttonNode && buttonNode->isHTMLElement() && buttonNode->hasTagName(inputTag) ? static_cast<HTMLInputElement*>(buttonNode) : 0;
}
diff --git a/Source/WebCore/rendering/RenderFileUploadControl.h b/Source/WebCore/rendering/RenderFileUploadControl.h
index 30ee6231c..11d959dac 100644
--- a/Source/WebCore/rendering/RenderFileUploadControl.h
+++ b/Source/WebCore/rendering/RenderFileUploadControl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2009, 2012 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
diff --git a/Source/WebCore/rendering/RenderFlexibleBox.cpp b/Source/WebCore/rendering/RenderFlexibleBox.cpp
index b025cd317..f2f993d7b 100644
--- a/Source/WebCore/rendering/RenderFlexibleBox.cpp
+++ b/Source/WebCore/rendering/RenderFlexibleBox.cpp
@@ -40,55 +40,13 @@ namespace WebCore {
// Normally, -1 and 0 are not valid in a HashSet, but these are relatively likely flex-order values. Instead,
// we make the two smallest int values invalid flex-order values (in the css parser code we clamp them to
// int min + 2).
-struct FlexOrderHashTraits : WTF::GenericHashTraits<int> {
+struct RenderFlexibleBox::FlexOrderHashTraits : WTF::GenericHashTraits<int> {
static const bool emptyValueIsZero = false;
static int emptyValue() { return std::numeric_limits<int>::min(); }
static void constructDeletedValue(int& slot) { slot = std::numeric_limits<int>::min() + 1; }
static bool isDeletedValue(int value) { return value == std::numeric_limits<int>::min() + 1; }
};
-typedef HashSet<int, DefaultHash<int>::Hash, FlexOrderHashTraits> FlexOrderHashSet;
-
-class RenderFlexibleBox::TreeOrderIterator {
-public:
- explicit TreeOrderIterator(RenderFlexibleBox* flexibleBox)
- : m_flexibleBox(flexibleBox)
- , m_currentChild(0)
- {
- }
-
- RenderBox* first()
- {
- reset();
- return next();
- }
-
- RenderBox* next()
- {
- m_currentChild = m_currentChild ? m_currentChild->nextSiblingBox() : m_flexibleBox->firstChildBox();
-
- if (m_currentChild)
- m_flexOrderValues.add(m_currentChild->style()->flexOrder());
-
- return m_currentChild;
- }
-
- void reset()
- {
- m_currentChild = 0;
- }
-
- const FlexOrderHashSet& flexOrderValues()
- {
- return m_flexOrderValues;
- }
-
-private:
- RenderFlexibleBox* m_flexibleBox;
- RenderBox* m_currentChild;
- FlexOrderHashSet m_flexOrderValues;
-};
-
class RenderFlexibleBox::FlexOrderIterator {
public:
FlexOrderIterator(RenderFlexibleBox* flexibleBox, const FlexOrderHashSet& flexOrderValues)
@@ -156,6 +114,84 @@ const char* RenderFlexibleBox::renderName() const
return "RenderFlexibleBox";
}
+static LayoutUnit marginLogicalWidthForChild(RenderBox* child, RenderStyle* parentStyle)
+{
+ // A margin has three types: fixed, percentage, and auto (variable).
+ // Auto and percentage margins become 0 when computing min/max width.
+ // Fixed margins can be added in as is.
+ Length marginLeft = child->style()->marginStartUsing(parentStyle);
+ Length marginRight = child->style()->marginEndUsing(parentStyle);
+ LayoutUnit margin = 0;
+ if (marginLeft.isFixed())
+ margin += marginLeft.value();
+ if (marginRight.isFixed())
+ margin += marginRight.value();
+ return margin;
+}
+
+void RenderFlexibleBox::computePreferredLogicalWidths()
+{
+ ASSERT(preferredLogicalWidthsDirty());
+
+ RenderStyle* styleToUse = style();
+ if (styleToUse->logicalWidth().isFixed() && styleToUse->logicalWidth().value() > 0)
+ m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeContentBoxLogicalWidth(styleToUse->logicalWidth().value());
+ else {
+ m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = 0;
+
+ for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
+ if (child->isPositioned())
+ continue;
+
+ LayoutUnit margin = marginLogicalWidthForChild(child, style());
+ bool hasOrthogonalWritingMode = child->isHorizontalWritingMode() != isHorizontalWritingMode();
+ LayoutUnit minPreferredLogicalWidth = hasOrthogonalWritingMode ? child->logicalHeight() : child->minPreferredLogicalWidth();
+ LayoutUnit maxPreferredLogicalWidth = hasOrthogonalWritingMode ? child->logicalHeight() : child->maxPreferredLogicalWidth();
+ minPreferredLogicalWidth += margin;
+ maxPreferredLogicalWidth += margin;
+ if (!isColumnFlow()) {
+ m_minPreferredLogicalWidth += minPreferredLogicalWidth;
+ m_maxPreferredLogicalWidth += maxPreferredLogicalWidth;
+ } else {
+ m_minPreferredLogicalWidth = std::max(minPreferredLogicalWidth, m_minPreferredLogicalWidth);
+ m_maxPreferredLogicalWidth = std::max(maxPreferredLogicalWidth, m_maxPreferredLogicalWidth);
+ }
+ }
+
+ m_maxPreferredLogicalWidth = std::max(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
+ }
+
+ LayoutUnit scrollbarWidth = 0;
+ if (hasOverflowClip()) {
+ if (isHorizontalWritingMode() && styleToUse->overflowY() == OSCROLL) {
+ layer()->setHasVerticalScrollbar(true);
+ scrollbarWidth = verticalScrollbarWidth();
+ } else if (!isHorizontalWritingMode() && styleToUse->overflowX() == OSCROLL) {
+ layer()->setHasHorizontalScrollbar(true);
+ scrollbarWidth = horizontalScrollbarHeight();
+ }
+ }
+
+ m_maxPreferredLogicalWidth += scrollbarWidth;
+ m_minPreferredLogicalWidth += scrollbarWidth;
+
+ if (styleToUse->logicalMinWidth().isFixed() && styleToUse->logicalMinWidth().value() > 0) {
+ m_maxPreferredLogicalWidth = std::max(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(styleToUse->logicalMinWidth().value()));
+ m_minPreferredLogicalWidth = std::max(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(styleToUse->logicalMinWidth().value()));
+ }
+
+ if (styleToUse->logicalMaxWidth().isFixed()) {
+ m_maxPreferredLogicalWidth = std::min(m_maxPreferredLogicalWidth, computeContentBoxLogicalWidth(styleToUse->logicalMaxWidth().value()));
+ m_minPreferredLogicalWidth = std::min(m_minPreferredLogicalWidth, computeContentBoxLogicalWidth(styleToUse->logicalMaxWidth().value()));
+ }
+
+ LayoutUnit borderAndPadding = borderAndPaddingLogicalWidth();
+ m_minPreferredLogicalWidth += borderAndPadding;
+ m_maxPreferredLogicalWidth += borderAndPadding;
+
+ setPreferredLogicalWidthsDirty(false);
+}
+
void RenderFlexibleBox::layoutBlock(bool relayoutChildren, int, BlockLayoutPass)
{
ASSERT(needsLayout());
@@ -465,26 +501,25 @@ LayoutUnit RenderFlexibleBox::preferredMainAxisContentExtentForChild(RenderBox*
void RenderFlexibleBox::layoutFlexItems(bool relayoutChildren)
{
+ FlexOrderHashSet flexOrderValues;
+ computeMainAxisPreferredSizes(relayoutChildren, flexOrderValues);
+
+ OrderedFlexItemList orderedChildren;
+ LayoutUnit preferredMainAxisExtent;
float totalPositiveFlexibility;
float totalNegativeFlexibility;
- TreeOrderIterator treeIterator(this);
+ FlexOrderIterator flexIterator(this, flexOrderValues);
+ computeFlexOrder(flexIterator, orderedChildren, preferredMainAxisExtent, totalPositiveFlexibility, totalNegativeFlexibility);
- WTF::Vector<LayoutUnit> preferredSizes;
- computeMainAxisPreferredSizes(relayoutChildren, treeIterator, preferredSizes, totalPositiveFlexibility, totalNegativeFlexibility);
- LayoutUnit preferredMainAxisExtent = 0;
- for (size_t i = 0; i < preferredSizes.size(); ++i)
- preferredMainAxisExtent += preferredSizes[i];
LayoutUnit availableFreeSpace = mainAxisContentExtent() - preferredMainAxisExtent;
-
- FlexOrderIterator flexIterator(this, treeIterator.flexOrderValues());
InflexibleFlexItemSize inflexibleItems;
WTF::Vector<LayoutUnit> childSizes;
- while (!runFreeSpaceAllocationAlgorithm(flexIterator, availableFreeSpace, totalPositiveFlexibility, totalNegativeFlexibility, inflexibleItems, childSizes)) {
+ while (!runFreeSpaceAllocationAlgorithm(orderedChildren, availableFreeSpace, totalPositiveFlexibility, totalNegativeFlexibility, inflexibleItems, childSizes)) {
ASSERT(totalPositiveFlexibility >= 0 && totalNegativeFlexibility >= 0);
ASSERT(inflexibleItems.size() > 0);
}
- layoutAndPlaceChildren(flexIterator, childSizes, availableFreeSpace, totalPositiveFlexibility);
+ layoutAndPlaceChildren(orderedChildren, childSizes, availableFreeSpace);
}
float RenderFlexibleBox::positiveFlexForChild(RenderBox* child) const
@@ -512,16 +547,14 @@ LayoutUnit RenderFlexibleBox::marginBoxAscent(RenderBox* child)
return ascent + flowAwareMarginBeforeForChild(child);
}
-void RenderFlexibleBox::computeMainAxisPreferredSizes(bool relayoutChildren, TreeOrderIterator& iterator, WTF::Vector<LayoutUnit>& preferredSizes, float& totalPositiveFlexibility, float& totalNegativeFlexibility)
+void RenderFlexibleBox::computeMainAxisPreferredSizes(bool relayoutChildren, FlexOrderHashSet& flexOrderValues)
{
- totalPositiveFlexibility = totalNegativeFlexibility = 0;
-
LayoutUnit flexboxAvailableContentExtent = mainAxisContentExtent();
- for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
- if (child->isPositioned()) {
- preferredSizes.append(0);
+ for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
+ flexOrderValues.add(child->style()->flexOrder());
+
+ if (child->isPositioned())
continue;
- }
child->clearOverrideSize();
if (mainAxisLengthForChild(child).isAuto()) {
@@ -530,35 +563,51 @@ void RenderFlexibleBox::computeMainAxisPreferredSizes(bool relayoutChildren, Tre
child->layoutIfNeeded();
}
- LayoutUnit preferredSize = mainAxisBorderAndPaddingExtentForChild(child) + preferredMainAxisContentExtentForChild(child);
-
// We set the margins because we want to make sure 'auto' has a margin
// of 0 and because if we're not auto sizing, we don't do a layout that
// computes the start/end margins.
if (isHorizontalFlow()) {
child->setMarginLeft(child->style()->marginLeft().calcMinValue(flexboxAvailableContentExtent));
child->setMarginRight(child->style()->marginRight().calcMinValue(flexboxAvailableContentExtent));
- preferredSize += child->marginLeft() + child->marginRight();
} else {
child->setMarginTop(child->style()->marginTop().calcMinValue(flexboxAvailableContentExtent));
child->setMarginBottom(child->style()->marginBottom().calcMinValue(flexboxAvailableContentExtent));
- preferredSize += child->marginTop() + child->marginBottom();
}
+ }
+}
+
+void RenderFlexibleBox::computeFlexOrder(FlexOrderIterator& iterator, OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, float& totalPositiveFlexibility, float& totalNegativeFlexibility)
+{
+ orderedChildren.clear();
+ preferredMainAxisExtent = 0;
+ totalPositiveFlexibility = totalNegativeFlexibility = 0;
+ for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
+ orderedChildren.append(child);
+ if (child->isPositioned())
+ continue;
- preferredSizes.append(preferredSize);
+ LayoutUnit childMainAxisExtent = mainAxisBorderAndPaddingExtentForChild(child) + preferredMainAxisContentExtentForChild(child);
+ if (isHorizontalFlow())
+ childMainAxisExtent += child->marginLeft() + child->marginRight();
+ else
+ childMainAxisExtent += child->marginTop() + child->marginBottom();
+ // FIXME: When implementing multiline, we would return here if adding
+ // the child's main axis extent would cause us to overflow.
+ preferredMainAxisExtent += childMainAxisExtent;
totalPositiveFlexibility += positiveFlexForChild(child);
totalNegativeFlexibility += negativeFlexForChild(child);
}
}
// Returns true if we successfully ran the algorithm and sized the flex items.
-bool RenderFlexibleBox::runFreeSpaceAllocationAlgorithm(FlexOrderIterator& iterator, LayoutUnit& availableFreeSpace, float& totalPositiveFlexibility, float& totalNegativeFlexibility, InflexibleFlexItemSize& inflexibleItems, WTF::Vector<LayoutUnit>& childSizes)
+bool RenderFlexibleBox::runFreeSpaceAllocationAlgorithm(const OrderedFlexItemList& children, LayoutUnit& availableFreeSpace, float& totalPositiveFlexibility, float& totalNegativeFlexibility, InflexibleFlexItemSize& inflexibleItems, WTF::Vector<LayoutUnit>& childSizes)
{
childSizes.clear();
LayoutUnit flexboxAvailableContentExtent = mainAxisContentExtent();
- for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
+ for (size_t i = 0; i < children.size(); ++i) {
+ RenderBox* child = children[i];
if (child->isPositioned()) {
childSizes.append(0);
continue;
@@ -600,27 +649,25 @@ bool RenderFlexibleBox::runFreeSpaceAllocationAlgorithm(FlexOrderIterator& itera
return true;
}
-static bool hasPackingSpace(LayoutUnit availableFreeSpace, float totalPositiveFlexibility)
-{
- return availableFreeSpace > 0 && !totalPositiveFlexibility;
-}
-
-static LayoutUnit initialPackingOffset(LayoutUnit availableFreeSpace, float totalPositiveFlexibility, EFlexPack flexPack, size_t numberOfChildren)
+static LayoutUnit initialPackingOffset(LayoutUnit availableFreeSpace, EFlexPack flexPack, size_t numberOfChildren)
{
- if (hasPackingSpace(availableFreeSpace, totalPositiveFlexibility)) {
+ if (availableFreeSpace > 0) {
if (flexPack == PackEnd)
return availableFreeSpace;
if (flexPack == PackCenter)
return availableFreeSpace / 2;
if (flexPack == PackDistribute && numberOfChildren)
return availableFreeSpace / (2 * numberOfChildren);
+ } else if (availableFreeSpace < 0) {
+ if (flexPack == PackCenter || flexPack == PackDistribute)
+ return availableFreeSpace / 2;
}
return 0;
}
-static LayoutUnit packingSpaceBetweenChildren(LayoutUnit availableFreeSpace, float totalPositiveFlexibility, EFlexPack flexPack, size_t numberOfChildren)
+static LayoutUnit packingSpaceBetweenChildren(LayoutUnit availableFreeSpace, EFlexPack flexPack, size_t numberOfChildren)
{
- if (hasPackingSpace(availableFreeSpace, totalPositiveFlexibility) && numberOfChildren > 1) {
+ if (availableFreeSpace > 0 && numberOfChildren > 1) {
if (flexPack == PackJustify)
return availableFreeSpace / (numberOfChildren - 1);
if (flexPack == PackDistribute)
@@ -664,10 +711,10 @@ static EFlexAlign flexAlignForChild(RenderBox* child)
return align;
}
-void RenderFlexibleBox::layoutAndPlaceChildren(FlexOrderIterator& iterator, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace, float totalPositiveFlexibility)
+void RenderFlexibleBox::layoutAndPlaceChildren(const OrderedFlexItemList& children, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace)
{
LayoutUnit mainAxisOffset = flowAwareBorderStart() + flowAwarePaddingStart();
- mainAxisOffset += initialPackingOffset(availableFreeSpace, totalPositiveFlexibility, style()->flexPack(), childSizes.size());
+ mainAxisOffset += initialPackingOffset(availableFreeSpace, style()->flexPack(), childSizes.size());
if (style()->flexDirection() == FlowRowReverse)
mainAxisOffset += isHorizontalFlow() ? verticalScrollbarWidth() : horizontalScrollbarHeight();
@@ -675,11 +722,11 @@ void RenderFlexibleBox::layoutAndPlaceChildren(FlexOrderIterator& iterator, cons
LayoutUnit totalMainExtent = mainAxisExtent();
LayoutUnit maxAscent = 0, maxDescent = 0; // Used when flex-align: baseline.
bool shouldFlipMainAxis = !isColumnFlow() && !isLeftToRightFlow();
- size_t i = 0;
- for (RenderBox* child = iterator.first(); child; child = iterator.next(), ++i) {
+ for (size_t i = 0; i < children.size(); ++i) {
+ RenderBox* child = children[i];
if (child->isPositioned()) {
prepareChildForPositionedLayout(child, mainAxisOffset, crossAxisOffset);
- mainAxisOffset += packingSpaceBetweenChildren(availableFreeSpace, totalPositiveFlexibility, style()->flexPack(), childSizes.size());
+ mainAxisOffset += packingSpaceBetweenChildren(availableFreeSpace, style()->flexPack(), childSizes.size());
continue;
}
LayoutUnit childPreferredSize = childSizes[i] + mainAxisBorderAndPaddingExtentForChild(child);
@@ -687,6 +734,7 @@ void RenderFlexibleBox::layoutAndPlaceChildren(FlexOrderIterator& iterator, cons
child->setChildNeedsLayout(true);
child->layoutIfNeeded();
+ LayoutUnit childCrossAxisExtent;
if (flexAlignForChild(child) == AlignBaseline) {
LayoutUnit ascent = marginBoxAscent(child);
LayoutUnit descent = (crossAxisMarginExtentForChild(child) + crossAxisExtentForChild(child)) - ascent;
@@ -694,10 +742,11 @@ void RenderFlexibleBox::layoutAndPlaceChildren(FlexOrderIterator& iterator, cons
maxAscent = std::max(maxAscent, ascent);
maxDescent = std::max(maxDescent, descent);
- if (crossAxisLength().isAuto())
- setCrossAxisExtent(std::max(crossAxisExtent(), crossAxisBorderAndPaddingExtent() + crossAxisMarginExtentForChild(child) + maxAscent + maxDescent + crossAxisScrollbarExtent()));
- } else if (crossAxisLength().isAuto())
- setCrossAxisExtent(std::max(crossAxisExtent(), crossAxisBorderAndPaddingExtent() + crossAxisMarginExtentForChild(child) + crossAxisExtentForChild(child) + crossAxisScrollbarExtent()));
+ childCrossAxisExtent = maxAscent + maxDescent;
+ } else
+ childCrossAxisExtent = crossAxisExtentForChild(child);
+ if (crossAxisLength().isAuto())
+ setCrossAxisExtent(std::max(crossAxisExtent(), crossAxisBorderAndPaddingExtent() + crossAxisMarginExtentForChild(child) + childCrossAxisExtent + crossAxisScrollbarExtent()));
mainAxisOffset += flowAwareMarginStartForChild(child);
@@ -709,7 +758,7 @@ void RenderFlexibleBox::layoutAndPlaceChildren(FlexOrderIterator& iterator, cons
setFlowAwareLocationForChild(child, childLocation);
mainAxisOffset += childMainExtent + flowAwareMarginEndForChild(child);
- mainAxisOffset += packingSpaceBetweenChildren(availableFreeSpace, totalPositiveFlexibility, style()->flexPack(), childSizes.size());
+ mainAxisOffset += packingSpaceBetweenChildren(availableFreeSpace, style()->flexPack(), childSizes.size());
if (isColumnFlow())
setLogicalHeight(mainAxisOffset + flowAwareBorderEnd() + flowAwarePaddingEnd() + scrollbarLogicalHeight());
@@ -719,27 +768,27 @@ void RenderFlexibleBox::layoutAndPlaceChildren(FlexOrderIterator& iterator, cons
// We have to do an extra pass for column-reverse to reposition the flex items since the start depends
// on the height of the flexbox, which we only know after we've positioned all the flex items.
computeLogicalHeight();
- layoutColumnReverse(iterator, childSizes, availableFreeSpace, totalPositiveFlexibility);
+ layoutColumnReverse(children, childSizes, availableFreeSpace);
}
- alignChildren(iterator, maxAscent);
+ alignChildren(children, maxAscent);
}
-void RenderFlexibleBox::layoutColumnReverse(FlexOrderIterator& iterator, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace, float totalPositiveFlexibility)
+void RenderFlexibleBox::layoutColumnReverse(const OrderedFlexItemList& children, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace)
{
// This is similar to the logic in layoutAndPlaceChildren, except we place the children
// starting from the end of the flexbox. We also don't need to layout anything since we're
// just moving the children to a new position.
LayoutUnit mainAxisOffset = logicalHeight() - flowAwareBorderEnd() - flowAwarePaddingEnd();
- mainAxisOffset -= initialPackingOffset(availableFreeSpace, totalPositiveFlexibility, style()->flexPack(), childSizes.size());
+ mainAxisOffset -= initialPackingOffset(availableFreeSpace, style()->flexPack(), childSizes.size());
mainAxisOffset -= isHorizontalFlow() ? verticalScrollbarWidth() : horizontalScrollbarHeight();
LayoutUnit crossAxisOffset = flowAwareBorderBefore() + flowAwarePaddingBefore();
- size_t i = 0;
- for (RenderBox* child = iterator.first(); child; child = iterator.next(), ++i) {
+ for (size_t i = 0; i < children.size(); ++i) {
+ RenderBox* child = children[i];
if (child->isPositioned()) {
child->layer()->setStaticBlockPosition(mainAxisOffset);
- mainAxisOffset -= packingSpaceBetweenChildren(availableFreeSpace, totalPositiveFlexibility, style()->flexPack(), childSizes.size());
+ mainAxisOffset -= packingSpaceBetweenChildren(availableFreeSpace, style()->flexPack(), childSizes.size());
continue;
}
mainAxisOffset -= mainAxisExtentForChild(child) + flowAwareMarginEndForChild(child);
@@ -750,7 +799,7 @@ void RenderFlexibleBox::layoutColumnReverse(FlexOrderIterator& iterator, const W
child->repaintDuringLayoutIfMoved(oldRect);
mainAxisOffset -= flowAwareMarginStartForChild(child);
- mainAxisOffset -= packingSpaceBetweenChildren(availableFreeSpace, totalPositiveFlexibility, style()->flexPack(), childSizes.size());
+ mainAxisOffset -= packingSpaceBetweenChildren(availableFreeSpace, style()->flexPack(), childSizes.size());
}
}
@@ -767,19 +816,12 @@ void RenderFlexibleBox::adjustAlignmentForChild(RenderBox* child, LayoutUnit del
child->repaintDuringLayoutIfMoved(oldRect);
}
-void RenderFlexibleBox::alignChildren(FlexOrderIterator& iterator, LayoutUnit maxAscent)
+void RenderFlexibleBox::alignChildren(const OrderedFlexItemList& children, LayoutUnit maxAscent)
{
LayoutUnit crossExtent = crossAxisExtent();
- for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
- // direction:rtl + flex-direction:column means the cross-axis direction is flipped.
- if (!style()->isLeftToRightDirection() && isColumnFlow()) {
- LayoutPoint location = flowAwareLocationForChild(child);
- location.setY(crossExtent - crossAxisExtentForChild(child) - location.y());
- setFlowAwareLocationForChild(child, location);
- }
-
- // FIXME: Make sure this does the right thing with column flows.
+ for (size_t i = 0; i < children.size(); ++i) {
+ RenderBox* child = children[i];
switch (flexAlignForChild(child)) {
case AlignAuto:
ASSERT_NOT_REACHED();
@@ -814,6 +856,14 @@ void RenderFlexibleBox::alignChildren(FlexOrderIterator& iterator, LayoutUnit ma
break;
}
}
+
+ // direction:rtl + flex-direction:column means the cross-axis direction is flipped.
+ if (!style()->isLeftToRightDirection() && isColumnFlow()) {
+ LayoutPoint location = flowAwareLocationForChild(child);
+ location.setY(crossExtent - crossAxisExtentForChild(child) - location.y());
+ setFlowAwareLocationForChild(child, location);
+ }
+
}
}
diff --git a/Source/WebCore/rendering/RenderFlexibleBox.h b/Source/WebCore/rendering/RenderFlexibleBox.h
index 0833217b6..0ee715f7e 100644
--- a/Source/WebCore/rendering/RenderFlexibleBox.h
+++ b/Source/WebCore/rendering/RenderFlexibleBox.h
@@ -43,15 +43,18 @@ public:
virtual const char* renderName() const;
virtual bool isFlexibleBox() const { return true; }
-
+ virtual void computePreferredLogicalWidths();
virtual void layoutBlock(bool relayoutChildren, int pageLogicalHeight = 0, BlockLayoutPass = NormalLayoutPass);
bool isHorizontalFlow() const;
private:
- class TreeOrderIterator;
+ struct FlexOrderHashTraits;
+ typedef HashSet<int, DefaultHash<int>::Hash, FlexOrderHashTraits> FlexOrderHashSet;
+
class FlexOrderIterator;
typedef WTF::HashMap<const RenderBox*, LayoutUnit> InflexibleFlexItemSize;
+ typedef WTF::Vector<RenderBox*> OrderedFlexItemList;
bool hasOrthogonalFlow(RenderBox* child) const;
bool isColumnFlow() const;
@@ -95,13 +98,14 @@ private:
LayoutUnit availableAlignmentSpaceForChild(RenderBox*);
LayoutUnit marginBoxAscent(RenderBox*);
- void computeMainAxisPreferredSizes(bool relayoutChildren, TreeOrderIterator&, WTF::Vector<LayoutUnit>&, float& totalPositiveFlexibility, float& totalNegativeFlexibility);
- bool runFreeSpaceAllocationAlgorithm(FlexOrderIterator&, LayoutUnit& availableFreeSpace, float& totalPositiveFlexibility, float& totalNegativeFlexibility, InflexibleFlexItemSize&, WTF::Vector<LayoutUnit>& childSizes);
+ void computeMainAxisPreferredSizes(bool relayoutChildren, FlexOrderHashSet&);
+ void computeFlexOrder(FlexOrderIterator&, OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, float& totalPositiveFlexibility, float& totalNegativeFlexibility);
+ bool runFreeSpaceAllocationAlgorithm(const OrderedFlexItemList&, LayoutUnit& availableFreeSpace, float& totalPositiveFlexibility, float& totalNegativeFlexibility, InflexibleFlexItemSize&, WTF::Vector<LayoutUnit>& childSizes);
void setLogicalOverrideSize(RenderBox* child, LayoutUnit childPreferredSize);
void prepareChildForPositionedLayout(RenderBox* child, LayoutUnit mainAxisOffset, LayoutUnit crossAxisOffset);
- void layoutAndPlaceChildren(FlexOrderIterator&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace, float totalPositiveFlexibility);
- void layoutColumnReverse(FlexOrderIterator&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace, float totalPositiveFlexibility);
- void alignChildren(FlexOrderIterator&, LayoutUnit maxAscent);
+ void layoutAndPlaceChildren(const OrderedFlexItemList&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace);
+ void layoutColumnReverse(const OrderedFlexItemList&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace);
+ void alignChildren(const OrderedFlexItemList&, LayoutUnit maxAscent);
};
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderFlowThread.cpp b/Source/WebCore/rendering/RenderFlowThread.cpp
index 9e39d9607..9e47d4dc9 100644
--- a/Source/WebCore/rendering/RenderFlowThread.cpp
+++ b/Source/WebCore/rendering/RenderFlowThread.cpp
@@ -51,7 +51,9 @@ RenderFlowThread::RenderFlowThread(Node* node, const AtomicString& flowThread)
, m_regionsInvalidated(false)
, m_regionsHaveUniformLogicalWidth(true)
, m_regionsHaveUniformLogicalHeight(true)
+ , m_overflow(false)
{
+ ASSERT(node->document()->cssRegionsEnabled());
setIsAnonymous(false);
setInRenderFlowThread();
}
@@ -137,6 +139,15 @@ void RenderFlowThread::removeFlowChild(RenderObject* child)
m_flowThreadChildList.remove(child);
}
+void RenderFlowThread::removeFlowChildInfo(RenderObject* child)
+{
+ if (child->isBox()) {
+ removeRenderBoxRegionInfo(toRenderBox(child));
+ if (child->canHaveRegionStyle())
+ clearRenderBoxCustomStyle(toRenderBox(child));
+ }
+}
+
// Compare two regions to determine in which one the content should flow first.
// The function returns true if the first passed region is "less" than the second passed region.
// If the first region appears before second region in DOM,
@@ -373,10 +384,10 @@ void RenderFlowThread::layout()
continue;
LayoutRect regionRect;
if (isHorizontalWritingMode()) {
- regionRect = LayoutRect(style()->direction() == LTR ? 0 : logicalWidth() - region->contentWidth(), logicalHeight, region->contentWidth(), region->contentHeight());
+ regionRect = LayoutRect(style()->direction() == LTR ? zeroLayoutUnit : logicalWidth() - region->contentWidth(), logicalHeight, region->contentWidth(), region->contentHeight());
logicalHeight += regionRect.height();
} else {
- regionRect = LayoutRect(logicalHeight, style()->direction() == LTR ? 0 : logicalWidth() - region->contentHeight(), region->contentWidth(), region->contentHeight());
+ regionRect = LayoutRect(logicalHeight, style()->direction() == LTR ? zeroLayoutUnit : logicalWidth() - region->contentHeight(), region->contentWidth(), region->contentHeight());
logicalHeight += regionRect.width();
}
region->setRegionRect(regionRect);
@@ -410,7 +421,7 @@ void RenderFlowThread::computeLogicalWidth()
LayoutUnit regionLogicalWidth = isHorizontalWritingMode() ? region->contentWidth() : region->contentHeight();
if (regionLogicalWidth != logicalWidth) {
- LayoutUnit logicalLeft = style()->direction() == LTR ? 0 : logicalWidth - regionLogicalWidth;
+ LayoutUnit logicalLeft = style()->direction() == LTR ? zeroLayoutUnit : logicalWidth - regionLogicalWidth;
region->setRenderBoxRegionInfo(this, logicalLeft, regionLogicalWidth, false);
}
}
@@ -445,7 +456,7 @@ void RenderFlowThread::paintIntoRegion(PaintInfo& paintInfo, RenderRegion* regio
LayoutRect regionClippingRect(paintOffset + (regionOverflowRect.location() - regionRect.location()), regionOverflowRect.size());
PaintInfo info(paintInfo);
- info.rect.intersect(regionClippingRect);
+ info.rect.intersect(pixelSnappedIntRect(regionClippingRect));
if (!info.rect.isEmpty()) {
context->save();
@@ -464,7 +475,7 @@ void RenderFlowThread::paintIntoRegion(PaintInfo& paintInfo, RenderRegion* regio
renderFlowThreadOffset = LayoutPoint(paintOffset - regionRect.location());
context->translate(renderFlowThreadOffset.x(), renderFlowThreadOffset.y());
- info.rect.moveBy(-renderFlowThreadOffset);
+ info.rect.moveBy(-roundedIntPoint(renderFlowThreadOffset));
layer()->paint(context, info.rect, 0, 0, region, RenderLayer::PaintLayerTemporaryClipRects);
@@ -491,7 +502,7 @@ bool RenderFlowThread::hitTestRegion(RenderRegion* region, const HitTestRequest&
LayoutPoint transformedPoint(pointInContainer.x() - renderFlowThreadOffset.x(), pointInContainer.y() - renderFlowThreadOffset.y());
// Always ignore clipping, since the RenderFlowThread has nothing to do with the bounds of the FrameView.
- HitTestRequest newRequest(request.type() & HitTestRequest::IgnoreClipping);
+ HitTestRequest newRequest(request.type() | HitTestRequest::IgnoreClipping);
RenderRegion* oldRegion = result.region();
result.setRegion(region);
@@ -531,14 +542,14 @@ void RenderFlowThread::repaintRectangleInRegions(const LayoutRect& repaintRect,
flipForWritingMode(flippedRegionRect); // Put the region rects into physical coordinates.
flipForWritingMode(flippedRegionOverflowRect);
- LayoutRect clippedRect(flippedRegionOverflowRect);
- clippedRect.intersect(repaintRect);
+ LayoutRect clippedRect(repaintRect);
+ clippedRect.intersect(flippedRegionOverflowRect);
if (clippedRect.isEmpty())
continue;
-
+
// Put the region rect into the region's physical coordinate space.
- clippedRect.setLocation(region->contentBoxRect().location() + (repaintRect.location() - flippedRegionRect.location()));
-
+ clippedRect.setLocation(region->contentBoxRect().location() + (clippedRect.location() - flippedRegionRect.location()));
+
// Now switch to the region's writing mode coordinate space and let it repaint itself.
region->flipForWritingMode(clippedRect);
LayoutStateDisabler layoutStateDisabler(view()); // We can't use layout state to repaint, since the region is somewhere else.
@@ -806,6 +817,9 @@ void RenderFlowThread::clearRenderBoxCustomStyle(const RenderBox* box,
void RenderFlowThread::setRegionRangeForBox(const RenderBox* box, LayoutUnit offsetFromLogicalTopOfFirstPage)
{
+ if (!hasRegions())
+ return;
+
// FIXME: Not right for differing writing-modes.
RenderRegion* startRegion = renderRegionForLine(offsetFromLogicalTopOfFirstPage, true);
RenderRegion* endRegion = renderRegionForLine(offsetFromLogicalTopOfFirstPage + box->logicalHeight(), true);
@@ -855,9 +869,40 @@ void RenderFlowThread::getRegionRangeForBox(const RenderBox* box, RenderRegion*&
WebKitNamedFlow* RenderFlowThread::ensureNamedFlow()
{
if (!m_namedFlow)
- m_namedFlow = WebKitNamedFlow::create();
+ m_namedFlow = WebKitNamedFlow::create(this);
return m_namedFlow.get();
}
+void RenderFlowThread::computeOverflowStateForRegions(LayoutUnit oldClientAfterEdge)
+{
+ LayoutUnit height = oldClientAfterEdge;
+ // FIXME: the visual overflow of middle region (if it is the last one to contain any content in a render flow thread)
+ // might not be taken into account because the render flow thread height is greater that that regions height + its visual overflow
+ // because of how computeLogicalHeight is implemented for RenderFlowThread (as a sum of all regions height).
+ // This means that the middle region will be marked as fit (even if it has visual overflow flowing into the next region)
+ if (hasRenderOverflow())
+ height = isHorizontalWritingMode() ? visualOverflowRect().maxY() : visualOverflowRect().maxX();
+
+ for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
+ RenderRegion* region = *iter;
+ if (!region->isValid()) {
+ region->setRegionState(RenderRegion::RegionUndefined);
+ continue;
+ }
+ LayoutUnit flowMin = height - (isHorizontalWritingMode() ? region->regionRect().y() : region->regionRect().x());
+ LayoutUnit flowMax = height - (isHorizontalWritingMode() ? region->regionRect().maxY() : region->regionRect().maxX());
+ RenderRegion::RegionState state = RenderRegion::RegionFit;
+ if (flowMin <= 0)
+ state = RenderRegion::RegionEmpty;
+ if (flowMax > 0)
+ state = RenderRegion::RegionOverflow;
+ region->setRegionState(state);
+ }
+
+ // With the regions overflow state computed we can also set the overflow for the named flow.
+ RenderRegion* lastReg = lastRegion();
+ m_overflow = lastReg && (lastReg->regionState() == RenderRegion::RegionOverflow);
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderFlowThread.h b/Source/WebCore/rendering/RenderFlowThread.h
index 4b1b36663..d05938891 100644
--- a/Source/WebCore/rendering/RenderFlowThread.h
+++ b/Source/WebCore/rendering/RenderFlowThread.h
@@ -74,7 +74,12 @@ public:
void addFlowChild(RenderObject* newChild, RenderObject* beforeChild = 0);
void removeFlowChild(RenderObject*);
+ void removeFlowChildInfo(RenderObject*);
bool hasChildren() const { return !m_flowThreadChildList.isEmpty(); }
+#ifndef NDEBUG
+ bool hasChild(RenderObject* child) const { return m_flowThreadChildList.contains(child); }
+ bool hasChildInfo(RenderObject* child) const { return child && child->isBox() && m_regionRangeMap.contains(toRenderBox(child)); }
+#endif
void addRegionToThread(RenderRegion*);
void removeRegionFromThread(RenderRegion*);
@@ -128,7 +133,9 @@ public:
const RenderRegion* oldStartRegion = 0, const RenderRegion* oldEndRegion = 0,
const RenderRegion* newStartRegion = 0, const RenderRegion* newEndRegion = 0);
WebKitNamedFlow* ensureNamedFlow();
+ void computeOverflowStateForRegions(LayoutUnit oldClientAfterEdge);
+ bool overflow() const { return m_overflow; }
private:
virtual const char* renderName() const { return "RenderFlowThread"; }
@@ -189,6 +196,7 @@ private:
bool m_regionsInvalidated;
bool m_regionsHaveUniformLogicalWidth;
bool m_regionsHaveUniformLogicalHeight;
+ bool m_overflow;
RefPtr<WebKitNamedFlow> m_namedFlow;
};
diff --git a/Source/WebCore/rendering/RenderFrameSet.cpp b/Source/WebCore/rendering/RenderFrameSet.cpp
index fc2c97f17..bcce93ef8 100644
--- a/Source/WebCore/rendering/RenderFrameSet.cpp
+++ b/Source/WebCore/rendering/RenderFrameSet.cpp
@@ -80,7 +80,7 @@ static Color borderFillColor()
return Color(208, 208, 208);
}
-void RenderFrameSet::paintColumnBorder(const PaintInfo& paintInfo, const LayoutRect& borderRect)
+void RenderFrameSet::paintColumnBorder(const PaintInfo& paintInfo, const IntRect& borderRect)
{
if (!paintInfo.rect.intersects(borderRect))
return;
@@ -100,7 +100,7 @@ void RenderFrameSet::paintColumnBorder(const PaintInfo& paintInfo, const LayoutR
}
}
-void RenderFrameSet::paintRowBorder(const PaintInfo& paintInfo, const LayoutRect& borderRect)
+void RenderFrameSet::paintRowBorder(const PaintInfo& paintInfo, const IntRect& borderRect)
{
if (!paintInfo.rect.intersects(borderRect))
return;
@@ -142,7 +142,7 @@ void RenderFrameSet::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
child->paint(paintInfo, adjustedPaintOffset);
xPos += m_cols.m_sizes[c];
if (borderThickness && m_cols.m_allowBorder[c + 1]) {
- paintColumnBorder(paintInfo, LayoutRect(adjustedPaintOffset.x() + xPos, adjustedPaintOffset.y() + yPos, borderThickness, height()));
+ paintColumnBorder(paintInfo, pixelSnappedIntRect(LayoutRect(adjustedPaintOffset.x() + xPos, adjustedPaintOffset.y() + yPos, borderThickness, height())));
xPos += borderThickness;
}
child = child->nextSibling();
@@ -151,7 +151,7 @@ void RenderFrameSet::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
}
yPos += m_rows.m_sizes[r];
if (borderThickness && m_rows.m_allowBorder[r + 1]) {
- paintRowBorder(paintInfo, LayoutRect(adjustedPaintOffset.x(), adjustedPaintOffset.y() + yPos, width(), borderThickness));
+ paintRowBorder(paintInfo, pixelSnappedIntRect(LayoutRect(adjustedPaintOffset.x(), adjustedPaintOffset.y() + yPos, width(), borderThickness)));
yPos += borderThickness;
}
}
@@ -571,7 +571,7 @@ void RenderFrameSet::positionFramesWithFlattening()
int height = m_rows.m_sizes[r];
for (int c = 0; c < cols; c++) {
- IntRect oldFrameRect = child->frameRect();
+ IntRect oldFrameRect = pixelSnappedIntRect(child->frameRect());
int width = m_cols.m_sizes[c];
@@ -619,7 +619,7 @@ void RenderFrameSet::positionFramesWithFlattening()
xPos = 0;
for (int c = 0; c < cols; c++) {
// ensure the rows and columns are filled
- IntRect oldRect = child->frameRect();
+ IntRect oldRect = pixelSnappedIntRect(child->frameRect());
child->setLocation(IntPoint(xPos, yPos));
child->setHeight(m_rows.m_sizes[r]);
@@ -802,11 +802,12 @@ bool RenderFrameSet::isChildAllowed(RenderObject* child, RenderStyle*) const
CursorDirective RenderFrameSet::getCursor(const LayoutPoint& point, Cursor& cursor) const
{
- if (canResizeRow(point)) {
+ IntPoint roundedPoint = roundedIntPoint(point);
+ if (canResizeRow(roundedPoint)) {
cursor = rowResizeCursor();
return SetCursor;
}
- if (canResizeColumn(point)) {
+ if (canResizeColumn(roundedPoint)) {
cursor = columnResizeCursor();
return SetCursor;
}
diff --git a/Source/WebCore/rendering/RenderFrameSet.h b/Source/WebCore/rendering/RenderFrameSet.h
index 373d0d02c..97be97428 100644
--- a/Source/WebCore/rendering/RenderFrameSet.h
+++ b/Source/WebCore/rendering/RenderFrameSet.h
@@ -68,8 +68,8 @@ public:
bool isResizingRow() const;
bool isResizingColumn() const;
- bool canResizeRow(const LayoutPoint&) const;
- bool canResizeColumn(const LayoutPoint&) const;
+ bool canResizeRow(const IntPoint&) const;
+ bool canResizeColumn(const IntPoint&) const;
void notifyFrameEdgeInfoChanged();
@@ -119,8 +119,8 @@ private:
void startResizing(GridAxis&, int position);
void continueResizing(GridAxis&, int position);
- void paintRowBorder(const PaintInfo&, const LayoutRect&);
- void paintColumnBorder(const PaintInfo&, const LayoutRect&);
+ void paintRowBorder(const PaintInfo&, const IntRect&);
+ void paintColumnBorder(const PaintInfo&, const IntRect&);
RenderObjectChildList m_children;
diff --git a/Source/WebCore/rendering/RenderImage.cpp b/Source/WebCore/rendering/RenderImage.cpp
index 9a0e576ad..de3e7e190 100644
--- a/Source/WebCore/rendering/RenderImage.cpp
+++ b/Source/WebCore/rendering/RenderImage.cpp
@@ -273,7 +273,7 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOf
context->setStrokeStyle(SolidStroke);
context->setStrokeColor(Color::lightGray, style()->colorSpace());
context->setFillColor(Color::transparent, style()->colorSpace());
- context->drawRect(LayoutRect(paintOffset.x() + leftBorder + leftPad, paintOffset.y() + topBorder + topPad, cWidth, cHeight));
+ context->drawRect(pixelSnappedIntRect(LayoutRect(paintOffset.x() + leftBorder + leftPad, paintOffset.y() + topBorder + topPad, cWidth, cHeight)));
bool errorPictureDrawn = false;
LayoutSize imageOffset;
@@ -299,7 +299,7 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOf
if (centerY < 0)
centerY = 0;
imageOffset = LayoutSize(leftBorder + leftPad + centerX + 1, topBorder + topPad + centerY + 1);
- context->drawImage(image.get(), style()->colorSpace(), IntRect(paintOffset + imageOffset, imageSize));
+ context->drawImage(image.get(), style()->colorSpace(), IntRect(roundedIntPoint(paintOffset + imageOffset), imageSize));
errorPictureDrawn = true;
}
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,
diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp
index ee6e8beea..a5b028b65 100644
--- a/Source/WebCore/rendering/RenderLayer.cpp
+++ b/Source/WebCore/rendering/RenderLayer.cpp
@@ -77,6 +77,7 @@
#include "Page.h"
#include "PlatformMouseEvent.h"
#include "RenderArena.h"
+#include "RenderFlowThread.h"
#include "RenderInline.h"
#include "RenderMarquee.h"
#include "RenderReplica.h"
@@ -357,7 +358,7 @@ void RenderLayer::updateLayerPositions(LayoutPoint* offsetFromRoot, UpdateLayerP
// as canUseConvertToLayerCoords may be true for an ancestor layer.
convertToLayerCoords(root(), offset);
}
- positionOverflowControls(toSize(offset));
+ positionOverflowControls(toSize(roundedIntPoint(offset)));
updateVisibilityStatus();
@@ -375,8 +376,8 @@ void RenderLayer::updateLayerPositions(LayoutPoint* offsetFromRoot, UpdateLayerP
ASSERT(!view->layoutStateEnabled());
RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint();
- IntRect oldRepaintRect = m_repaintRect;
- IntRect oldOutlineBox = m_outlineBox;
+ LayoutRect oldRepaintRect = m_repaintRect;
+ LayoutRect oldOutlineBox = m_outlineBox;
computeRepaintRects(offsetFromRoot);
// FIXME: Should ASSERT that value calculated for m_outlineBox using the cached offset is the same
// as the value not using the cached offset, but we can't due to https://bugs.webkit.org/show_bug.cgi?id=37048
@@ -433,7 +434,7 @@ LayoutRect RenderLayer::repaintRectIncludingDescendants() const
return repaintRect;
}
-void RenderLayer::computeRepaintRects(IntPoint* offsetFromRoot)
+void RenderLayer::computeRepaintRects(LayoutPoint* offsetFromRoot)
{
ASSERT(!m_visibleContentStatusDirty);
@@ -453,8 +454,9 @@ void RenderLayer::clearRepaintRects()
void RenderLayer::updateLayerPositionsAfterScroll(UpdateLayerPositionsAfterScrollFlags flags)
{
- ASSERT(!m_visibleDescendantStatusDirty);
- ASSERT(!m_visibleContentStatusDirty);
+ // FIXME: This shouldn't be needed, but there are some corner cases where
+ // these flags are still dirty. Update so that the check below is valid.
+ updateVisibilityStatus();
// If we have no visible content and no visible descendants, there is no point recomputing
// our rectangles as they will be empty. If our visibility changes, we are expected to
@@ -1191,22 +1193,16 @@ void RenderLayer::removeOnlyThisLayer()
// Dirty the clip rects.
clearClipRectsIncludingDescendants();
- // Remove us from the parent.
- RenderLayer* parent = m_parent;
RenderLayer* nextSib = nextSibling();
bool hasLayerOffset;
const LayoutPoint offsetFromRootBeforeMove = computeOffsetFromRoot(hasLayerOffset);
- parent->removeChild(this);
-
- if (reflection())
- removeChild(reflectionLayer());
// Now walk our kids and reattach them to our parent.
RenderLayer* current = m_first;
while (current) {
RenderLayer* next = current->nextSibling();
removeChild(current);
- parent->addChild(current, nextSib);
+ m_parent->addChild(current, nextSib);
current->setRepaintStatus(NeedsFullRepaint);
LayoutPoint offsetFromRoot = offsetFromRootBeforeMove;
// updateLayerPositions depends on hasLayer() already being false for proper layout.
@@ -1215,6 +1211,11 @@ void RenderLayer::removeOnlyThisLayer()
current = next;
}
+ // Remove us from the parent.
+ if (reflection())
+ removeChild(reflectionLayer());
+ m_parent->removeChild(this);
+
m_renderer->destroyLayer();
}
@@ -1237,8 +1238,21 @@ void RenderLayer::insertOnlyThisLayer()
clearClipRectsIncludingDescendants();
}
-void
-RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutPoint& location) const
+void RenderLayer::convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntPoint& roundedLocation) const
+{
+ LayoutPoint location = roundedLocation;
+ convertToLayerCoords(ancestorLayer, location);
+ roundedLocation = roundedIntPoint(location);
+}
+
+void RenderLayer::convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntRect& roundedRect) const
+{
+ LayoutRect rect = roundedRect;
+ convertToLayerCoords(ancestorLayer, rect);
+ roundedRect = pixelSnappedIntRect(rect);
+}
+
+void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutPoint& location) const
{
if (ancestorLayer == this)
return;
@@ -1325,8 +1339,7 @@ RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutPoint&
location += toSize(m_topLeft);
}
-void
-RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutRect& rect) const
+void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutRect& rect) const
{
LayoutPoint delta;
convertToLayerCoords(ancestorLayer, delta);
@@ -1578,7 +1591,7 @@ void RenderLayer::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignm
LayoutRect viewRect = frameView->visibleContentRect();
LayoutRect r = getRectToExpose(viewRect, rect, alignX, alignY);
- frameView->setScrollPosition(r.location());
+ frameView->setScrollPosition(roundedIntPoint(r.location()));
// This is the outermost view of a web page, so after scrolling this view we
// scroll its container by calling Page::scrollRectIntoView.
@@ -1587,7 +1600,7 @@ void RenderLayer::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignm
// The canAutoscroll function in EventHandler also knows about this.
if (Frame* frame = frameView->frame()) {
if (Page* page = frame->page())
- page->chrome()->scrollRectIntoView(rect);
+ page->chrome()->scrollRectIntoView(pixelSnappedIntRect(rect));
}
}
}
@@ -1725,29 +1738,29 @@ void RenderLayer::resize(const PlatformMouseEvent& evt, const LayoutSize& oldOff
LayoutSize difference = (currentSize + newOffset - adjustedOldOffset).expandedTo(minimumSize) - currentSize;
ASSERT(element->isStyledElement());
- StylePropertySet* styleDeclaration = static_cast<StyledElement*>(element)->ensureInlineStyleDecl();
+ StyledElement* styledElement = static_cast<StyledElement*>(element);
bool isBoxSizingBorder = renderer->style()->boxSizing() == BORDER_BOX;
if (resize != RESIZE_VERTICAL && difference.width()) {
if (element->isFormControlElement()) {
// Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
- styleDeclaration->setProperty(CSSPropertyMarginLeft, String::number(renderer->marginLeft() / zoomFactor) + "px", false);
- styleDeclaration->setProperty(CSSPropertyMarginRight, String::number(renderer->marginRight() / zoomFactor) + "px", false);
+ styledElement->setInlineStyleProperty(CSSPropertyMarginLeft, String::number(renderer->marginLeft() / zoomFactor) + "px", false);
+ styledElement->setInlineStyleProperty(CSSPropertyMarginRight, String::number(renderer->marginRight() / zoomFactor) + "px", false);
}
- LayoutUnit baseWidth = renderer->width() - (isBoxSizingBorder ? 0 : renderer->borderAndPaddingWidth());
+ LayoutUnit baseWidth = renderer->width() - (isBoxSizingBorder ? zeroLayoutUnit : renderer->borderAndPaddingWidth());
baseWidth = baseWidth / zoomFactor;
- styleDeclaration->setProperty(CSSPropertyWidth, String::number(baseWidth + difference.width()) + "px", false);
+ styledElement->setInlineStyleProperty(CSSPropertyWidth, String::number(baseWidth + difference.width()) + "px", false);
}
if (resize != RESIZE_HORIZONTAL && difference.height()) {
if (element->isFormControlElement()) {
// Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
- styleDeclaration->setProperty(CSSPropertyMarginTop, String::number(renderer->marginTop() / zoomFactor) + "px", false);
- styleDeclaration->setProperty(CSSPropertyMarginBottom, String::number(renderer->marginBottom() / zoomFactor) + "px", false);
+ styledElement->setInlineStyleProperty(CSSPropertyMarginTop, String::number(renderer->marginTop() / zoomFactor) + "px", false);
+ styledElement->setInlineStyleProperty(CSSPropertyMarginBottom, String::number(renderer->marginBottom() / zoomFactor) + "px", false);
}
- LayoutUnit baseHeight = renderer->height() - (isBoxSizingBorder ? 0 : renderer->borderAndPaddingHeight());
+ LayoutUnit baseHeight = renderer->height() - (isBoxSizingBorder ? zeroLayoutUnit : renderer->borderAndPaddingHeight());
baseHeight = baseHeight / zoomFactor;
- styleDeclaration->setProperty(CSSPropertyHeight, String::number(baseHeight + difference.height()) + "px", false);
+ styledElement->setInlineStyleProperty(CSSPropertyHeight, String::number(baseHeight + difference.height()) + "px", false);
}
document->updateLayout();
@@ -1788,7 +1801,7 @@ IntPoint RenderLayer::minimumScrollPosition() const
IntPoint RenderLayer::maximumScrollPosition() const
{
// FIXME: m_scrollSize may not be up-to-date if m_scrollDimensionsDirty is true.
- return scrollOrigin() + m_scrollSize - visibleContentRect(true).size();
+ return scrollOrigin() + roundedIntSize(m_scrollSize) - visibleContentRect(true).size();
}
IntRect RenderLayer::visibleContentRect(bool includeScrollbars) const
@@ -1850,7 +1863,7 @@ IntRect RenderLayer::scrollCornerRect() const
bool hasVerticalBar = verticalScrollbar();
bool hasResizer = renderer()->style()->resize() != RESIZE_NONE;
if ((hasHorizontalBar && hasVerticalBar) || (hasResizer && (hasHorizontalBar || hasVerticalBar)))
- return cornerRect(this, renderBox()->borderBoxRect());
+ return cornerRect(this, pixelSnappedIntRect(renderBox()->borderBoxRect()));
return IntRect();
}
@@ -1869,7 +1882,7 @@ IntRect RenderLayer::scrollCornerAndResizerRect() const
return IntRect();
IntRect scrollCornerAndResizer = scrollCornerRect();
if (scrollCornerAndResizer.isEmpty())
- scrollCornerAndResizer = resizerCornerRect(this, box->borderBoxRect());
+ scrollCornerAndResizer = resizerCornerRect(this, pixelSnappedIntRect(box->borderBoxRect()));
return scrollCornerAndResizer;
}
@@ -2131,12 +2144,12 @@ int RenderLayer::horizontalScrollbarHeight(OverlayScrollbarSizeRelevancy relevan
return m_hBar->height();
}
-LayoutSize RenderLayer::offsetFromResizeCorner(const LayoutPoint& absolutePoint) const
+IntSize RenderLayer::offsetFromResizeCorner(const IntPoint& absolutePoint) const
{
// Currently the resize corner is always the bottom right corner
// FIXME: This assumes the location is 0, 0. Is this guaranteed to always be the case?
- LayoutPoint bottomRight = toPoint(size());
- LayoutPoint localPoint = absoluteToContents(absolutePoint);
+ IntPoint bottomRight = toPoint(size());
+ IntPoint localPoint = roundedIntPoint(absoluteToContents(absolutePoint));
return localPoint - bottomRight;
}
@@ -2145,7 +2158,7 @@ bool RenderLayer::hasOverflowControls() const
return m_hBar || m_vBar || m_scrollCorner || renderer()->style()->resize() != RESIZE_NONE;
}
-void RenderLayer::positionOverflowControls(const LayoutSize& offsetFromLayer)
+void RenderLayer::positionOverflowControls(const IntSize& offsetFromLayer)
{
if (!m_hBar && !m_vBar && (!renderer()->hasOverflowClip() || renderer()->style()->resize() == RESIZE_NONE))
return;
@@ -2154,7 +2167,7 @@ void RenderLayer::positionOverflowControls(const LayoutSize& offsetFromLayer)
if (!box)
return;
- const IntRect borderBox = box->borderBoxRect();
+ const IntRect borderBox = pixelSnappedIntRect(box->borderBoxRect());
const IntRect& scrollCorner = scrollCornerRect();
IntRect absBounds(borderBox.location() + offsetFromLayer, borderBox.size());
if (m_vBar)
@@ -2397,7 +2410,7 @@ void RenderLayer::updateScrollInfoAfterLayout()
updateOverflowStatus(horizontalOverflow, verticalOverflow);
}
-void RenderLayer::paintOverflowControls(GraphicsContext* context, const LayoutPoint& paintOffset, const LayoutRect& damageRect, bool paintingOverlayControls)
+void RenderLayer::paintOverflowControls(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect, bool paintingOverlayControls)
{
// Don't do anything if we have no overflow.
if (!renderer()->hasOverflowClip())
@@ -2421,7 +2434,7 @@ void RenderLayer::paintOverflowControls(GraphicsContext* context, const LayoutPo
if (paintingOverlayControls && !hasOverlayScrollbars())
return;
- LayoutPoint adjustedPaintOffset = paintOffset;
+ IntPoint adjustedPaintOffset = paintOffset;
if (paintingOverlayControls)
adjustedPaintOffset = m_cachedOverlayScrollbarOffset;
@@ -2457,12 +2470,12 @@ void RenderLayer::paintOverflowControls(GraphicsContext* context, const LayoutPo
paintResizer(context, adjustedPaintOffset, damageRect);
}
-void RenderLayer::paintScrollCorner(GraphicsContext* context, const LayoutPoint& paintOffset, const LayoutRect& damageRect)
+void RenderLayer::paintScrollCorner(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect)
{
RenderBox* box = renderBox();
ASSERT(box);
- LayoutRect absRect = scrollCornerRect();
+ IntRect absRect = scrollCornerRect();
absRect.moveBy(paintOffset);
if (!absRect.intersects(damageRect))
return;
@@ -2483,7 +2496,7 @@ void RenderLayer::paintScrollCorner(GraphicsContext* context, const LayoutPoint&
context->fillRect(absRect, Color::white, box->style()->colorSpace());
}
-void RenderLayer::drawPlatformResizerImage(GraphicsContext* context, LayoutRect resizerCornerRect)
+void RenderLayer::drawPlatformResizerImage(GraphicsContext* context, IntRect resizerCornerRect)
{
float deviceScaleFactor = WebCore::deviceScaleFactor(renderer()->frame());
@@ -2504,7 +2517,7 @@ void RenderLayer::drawPlatformResizerImage(GraphicsContext* context, LayoutRect
context->drawImage(resizeCornerImage.get(), renderer()->style()->colorSpace(), imageRect);
}
-void RenderLayer::paintResizer(GraphicsContext* context, const LayoutPoint& paintOffset, const LayoutRect& damageRect)
+void RenderLayer::paintResizer(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect)
{
if (renderer()->style()->resize() == RESIZE_NONE)
return;
@@ -2512,7 +2525,7 @@ void RenderLayer::paintResizer(GraphicsContext* context, const LayoutPoint& pain
RenderBox* box = renderBox();
ASSERT(box);
- LayoutRect absRect = resizerCornerRect(this, box->borderBoxRect());
+ IntRect absRect = resizerCornerRect(this, pixelSnappedIntRect(box->borderBoxRect()));
absRect.moveBy(paintOffset);
if (!absRect.intersects(damageRect))
return;
@@ -2534,8 +2547,8 @@ void RenderLayer::paintResizer(GraphicsContext* context, const LayoutPoint& pain
if (!hasOverlayScrollbars() && (m_vBar || m_hBar)) {
GraphicsContextStateSaver stateSaver(*context);
context->clip(absRect);
- LayoutRect largerCorner = absRect;
- largerCorner.setSize(LayoutSize(largerCorner.width() + 1, largerCorner.height() + 1));
+ IntRect largerCorner = absRect;
+ largerCorner.setSize(IntSize(largerCorner.width() + 1, largerCorner.height() + 1));
context->setStrokeColor(Color(makeRGB(217, 217, 217)), ColorSpaceDeviceRGB);
context->setStrokeThickness(1.0f);
context->setFillColor(Color::transparent, ColorSpaceDeviceRGB);
@@ -2543,7 +2556,7 @@ void RenderLayer::paintResizer(GraphicsContext* context, const LayoutPoint& pain
}
}
-bool RenderLayer::isPointInResizeControl(const LayoutPoint& absolutePoint) const
+bool RenderLayer::isPointInResizeControl(const IntPoint& absolutePoint) const
{
if (!renderer()->hasOverflowClip() || renderer()->style()->resize() == RESIZE_NONE)
return false;
@@ -2551,13 +2564,13 @@ bool RenderLayer::isPointInResizeControl(const LayoutPoint& absolutePoint) const
RenderBox* box = renderBox();
ASSERT(box);
- LayoutPoint localPoint = absoluteToContents(absolutePoint);
+ IntPoint localPoint = roundedIntPoint(absoluteToContents(absolutePoint));
- LayoutRect localBounds(0, 0, box->width(), box->height());
+ IntRect localBounds(0, 0, box->pixelSnappedWidth(), box->pixelSnappedHeight());
return resizerCornerRect(this, localBounds).contains(localPoint);
}
-bool RenderLayer::hitTestOverflowControls(HitTestResult& result, const LayoutPoint& localPoint)
+bool RenderLayer::hitTestOverflowControls(HitTestResult& result, const IntPoint& localPoint)
{
if (!m_hBar && !m_vBar && (!renderer()->hasOverflowClip() || renderer()->style()->resize() == RESIZE_NONE))
return false;
@@ -2567,7 +2580,7 @@ bool RenderLayer::hitTestOverflowControls(HitTestResult& result, const LayoutPoi
IntRect resizeControlRect;
if (renderer()->style()->resize() != RESIZE_NONE) {
- resizeControlRect = resizerCornerRect(this, box->borderBoxRect());
+ resizeControlRect = resizerCornerRect(this, pixelSnappedIntRect(box->borderBoxRect()));
if (resizeControlRect.contains(localPoint))
return true;
}
@@ -2645,7 +2658,7 @@ void RenderLayer::clipToRect(RenderLayer* rootLayer, GraphicsContext* context, c
if (clipRect.rect() == paintDirtyRect)
return;
context->save();
- context->clip(clipRect.rect());
+ context->clip(pixelSnappedIntRect(clipRect.rect()));
if (!clipRect.hasRadius())
return;
@@ -2946,7 +2959,7 @@ void RenderLayer::paintLayerContents(RenderLayer* rootLayer, GraphicsContext* co
if (isPaintingOverlayScrollbars) {
clipToRect(rootLayer, context, paintDirtyRect, damageRect);
- paintOverflowControls(context, paintOffset, damageRect.rect(), true);
+ paintOverflowControls(context, roundedIntPoint(paintOffset), pixelSnappedIntRect(damageRect.rect()), true);
restoreClip(context, paintDirtyRect, damageRect);
}
@@ -3110,9 +3123,9 @@ bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result)
{
renderer()->document()->updateLayout();
- LayoutRect hitTestArea = renderer()->view()->documentRect();
+ IntRect hitTestArea = renderer()->isRenderFlowThread() ? toRenderFlowThread(renderer())->borderBoxRect() : renderer()->view()->documentRect();
if (!request.ignoreClipping())
- hitTestArea.intersect(frameVisibleRect(renderer()));
+ hitTestArea.intersect(pixelSnappedIntRect(frameVisibleRect(renderer())));
RenderLayer* insideLayer = hitTestLayer(this, 0, request, result, hitTestArea, result.point(), false);
if (!insideLayer) {
@@ -3747,7 +3760,7 @@ void RenderLayer::calculateRects(const RenderLayer* rootLayer, RenderRegion* reg
backgroundRect.intersect(layerBoundsWithVisualOverflow);
} else {
// Shift the bounds to be for our region only.
- LayoutRect bounds = renderBox()->borderBoxRectInRegion(region);
+ LayoutRect bounds = pixelSnappedIntRect(renderBox()->borderBoxRectInRegion(region));
bounds.moveBy(offset);
backgroundRect.intersect(bounds);
}
@@ -4269,7 +4282,7 @@ void RenderLayer::setBackingNeedsRepaintInRect(const LayoutRect& r)
if (view)
view->repaintViewRectangle(absRect);
} else
- backing()->setContentsNeedDisplayInRect(r);
+ backing()->setContentsNeedDisplayInRect(pixelSnappedIntRect(r));
}
// Since we're only painting non-composited layers, we know that they all share the same repaintContainer.
diff --git a/Source/WebCore/rendering/RenderLayer.h b/Source/WebCore/rendering/RenderLayer.h
index bb4797bb2..4c5be0cdc 100644
--- a/Source/WebCore/rendering/RenderLayer.h
+++ b/Source/WebCore/rendering/RenderLayer.h
@@ -295,8 +295,6 @@ public:
// Scrolling methods for layers that can scroll their overflow.
void scrollByRecursively(LayoutUnit xDelta, LayoutUnit yDelta, ScrollOffsetClamping = ScrollOffsetUnclamped);
- LayoutSize scrolledContentOffset() const { return scrollOffset() + m_scrollOverflow; }
-
int scrollXOffset() const { return m_scrollOffset.width() + scrollOrigin().x(); }
int scrollYOffset() const { return m_scrollOffset.height() + scrollOrigin().y(); }
IntSize scrollOffset() const { return IntSize(scrollXOffset(), scrollYOffset()); }
@@ -327,13 +325,13 @@ public:
int horizontalScrollbarHeight(OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
bool hasOverflowControls() const;
- bool isPointInResizeControl(const LayoutPoint& absolutePoint) const;
- bool hitTestOverflowControls(HitTestResult&, const LayoutPoint& localPoint);
- LayoutSize offsetFromResizeCorner(const LayoutPoint& absolutePoint) const;
+ bool isPointInResizeControl(const IntPoint& absolutePoint) const;
+ bool hitTestOverflowControls(HitTestResult&, const IntPoint& localPoint);
+ IntSize offsetFromResizeCorner(const IntPoint& absolutePoint) const;
- void paintOverflowControls(GraphicsContext*, const LayoutPoint&, const LayoutRect& damageRect, bool paintingOverlayControls = false);
- void paintScrollCorner(GraphicsContext*, const LayoutPoint&, const LayoutRect& damageRect);
- void paintResizer(GraphicsContext*, const LayoutPoint&, const LayoutRect& damageRect);
+ void paintOverflowControls(GraphicsContext*, const IntPoint&, const IntRect& damageRect, bool paintingOverlayControls = false);
+ void paintScrollCorner(GraphicsContext*, const IntPoint&, const IntRect& damageRect);
+ void paintResizer(GraphicsContext*, const IntPoint&, const IntRect& damageRect);
void updateScrollInfoAfterLayout();
@@ -425,6 +423,8 @@ public:
RenderLayer* ancestorCompositingLayer() const { return enclosingCompositingLayer(false); }
#endif
+ void convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntPoint& location) const;
+ void convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntRect&) const;
void convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutPoint& location) const;
void convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutRect&) const;
@@ -524,6 +524,9 @@ public:
#if ENABLE(CSS_FILTERS)
virtual void filterNeedsRepaint();
+ bool hasFilter() const { return renderer()->hasFilter(); }
+#else
+ bool hasFilter() const { return false; }
#endif
// Overloaded new operator. Derived classes must override operator new
@@ -565,7 +568,7 @@ public:
private:
void updateZOrderListsSlowCase();
- void computeRepaintRects(IntPoint* offsetFromRoot = 0);
+ void computeRepaintRects(LayoutPoint* offsetFromRoot = 0);
void clearRepaintRects();
void clipToRect(RenderLayer* rootLayer, GraphicsContext*, const LayoutRect& paintDirtyRect, const ClipRect&,
@@ -574,6 +577,9 @@ private:
bool shouldRepaintAfterLayout() const;
+ friend IntSize RenderBox::scrolledContentOffset() const;
+ IntSize scrolledContentOffset() const { return scrollOffset() + m_scrollOverflow; }
+
// The normal operator new is disallowed on all render objects.
void* operator new(size_t) throw();
@@ -710,11 +716,11 @@ private:
// Convert a point in absolute coords into layer coords, taking transforms into account
LayoutPoint absoluteToContents(const LayoutPoint&) const;
- void positionOverflowControls(const LayoutSize&);
+ void positionOverflowControls(const IntSize&);
void updateScrollCornerStyle();
void updateResizerStyle();
- void drawPlatformResizerImage(GraphicsContext*, LayoutRect resizerCornerRect);
+ void drawPlatformResizerImage(GraphicsContext*, IntRect resizerCornerRect);
void updatePagination();
bool isPaginated() const { return m_isPaginated; }
@@ -818,7 +824,7 @@ protected:
LayoutSize m_scrollOverflow;
// The width/height of our scrolled area.
- IntSize m_scrollSize;
+ LayoutSize m_scrollSize;
// For layers with overflow, we have a pair of scrollbars.
RefPtr<Scrollbar> m_hBar;
@@ -840,7 +846,7 @@ protected:
const RenderLayer* m_clipRectsRoot; // Root layer used to compute clip rects.
#endif
- LayoutPoint m_cachedOverlayScrollbarOffset;
+ IntPoint m_cachedOverlayScrollbarOffset;
RenderMarquee* m_marquee; // Used by layers with overflow:marquee
diff --git a/Source/WebCore/rendering/RenderLayerBacking.cpp b/Source/WebCore/rendering/RenderLayerBacking.cpp
index 9503a8275..f559970b4 100644
--- a/Source/WebCore/rendering/RenderLayerBacking.cpp
+++ b/Source/WebCore/rendering/RenderLayerBacking.cpp
@@ -70,7 +70,7 @@ using namespace HTMLNames;
static bool hasBoxDecorations(const RenderStyle*);
static bool hasBoxDecorationsOrBackground(const RenderObject*);
static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle*);
-static LayoutRect clipBox(RenderBox* renderer);
+static IntRect clipBox(RenderBox* renderer);
static inline bool isAcceleratedCanvas(RenderObject* renderer)
{
@@ -101,7 +101,7 @@ RenderLayerBacking::RenderLayerBacking(RenderLayer* layer)
if (page && frame && page->mainFrame() == frame) {
m_isMainFrameRenderViewLayer = true;
-#if ENABLE(THREADED_SCROLLING)
+#if PLATFORM(MAC)
// FIXME: It's a little weird that we base this decision on whether there's a scrolling coordinator or not.
if (page->scrollingCoordinator())
m_usingTiledCacheLayer = true;
@@ -229,7 +229,7 @@ static bool layerOrAncestorIsFullScreen(RenderLayer* layer)
void RenderLayerBacking::updateCompositedBounds()
{
- LayoutRect layerBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer);
+ IntRect layerBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer);
// Clip to the size of the document or enclosing overflow-scroll layer.
// If this or an ancestor is transformed, we can't currently compute the correct rect to intersect with.
@@ -254,7 +254,7 @@ void RenderLayerBacking::updateCompositedBounds()
m_owningLayer->convertToLayerCoords(rootLayer, delta);
clippingBounds.move(-delta.x(), -delta.y());
- layerBounds.intersect(clippingBounds);
+ layerBounds.intersect(pixelSnappedIntRect(clippingBounds));
}
// If the element has a transform-origin that has fixed lengths, and the renderer has zero size,
@@ -371,7 +371,7 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration()
return layerConfigChanged;
}
-static LayoutRect clipBox(RenderBox* renderer)
+static IntRect clipBox(RenderBox* renderer)
{
LayoutRect result = PaintInfo::infiniteRect();
if (renderer->hasOverflowClip())
@@ -380,7 +380,7 @@ static LayoutRect clipBox(RenderBox* renderer)
if (renderer->hasClip())
result.intersect(renderer->clipRect(LayoutPoint(), 0)); // FIXME: Incorrect for CSS regions.
- return result;
+ return pixelSnappedIntRect(result);
}
void RenderLayerBacking::updateGraphicsLayerGeometry()
@@ -416,24 +416,24 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
RenderLayer* compAncestor = m_owningLayer->ancestorCompositingLayer();
// We compute everything relative to the enclosing compositing layer.
- LayoutRect ancestorCompositingBounds;
+ IntRect ancestorCompositingBounds;
if (compAncestor) {
ASSERT(compAncestor->backing());
- ancestorCompositingBounds = compAncestor->backing()->compositedBounds();
+ ancestorCompositingBounds = pixelSnappedIntRect(compAncestor->backing()->compositedBounds());
}
- LayoutRect localCompositingBounds = compositedBounds();
+ IntRect localCompositingBounds = pixelSnappedIntRect(compositedBounds());
- LayoutRect relativeCompositingBounds(localCompositingBounds);
- LayoutPoint delta;
- m_owningLayer->convertToLayerCoords(compAncestor, delta);
+ IntRect relativeCompositingBounds(localCompositingBounds);
+ IntPoint delta;
+ m_owningLayer->convertToPixelSnappedLayerCoords(compAncestor, delta);
relativeCompositingBounds.moveBy(delta);
- LayoutPoint graphicsLayerParentLocation;
+ IntPoint graphicsLayerParentLocation;
if (compAncestor && compAncestor->backing()->hasClippingLayer()) {
// If the compositing ancestor has a layer to clip children, we parent in that, and therefore
// position relative to it.
- LayoutRect clippingBox = clipBox(toRenderBox(compAncestor->renderer()));
+ IntRect clippingBox = clipBox(toRenderBox(compAncestor->renderer()));
graphicsLayerParentLocation = clippingBox.location();
} else if (compAncestor)
graphicsLayerParentLocation = ancestorCompositingBounds.location();
@@ -444,7 +444,7 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
// Call calculateRects to get the backgroundRect which is what is used to clip the contents of this
// layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
// for a compositing layer, rootLayer is the layer itself.
- LayoutRect parentClipRect = m_owningLayer->backgroundClipRect(compAncestor, 0, true).rect(); // FIXME: Incorrect for CSS regions.
+ IntRect parentClipRect = pixelSnappedIntRect(m_owningLayer->backgroundClipRect(compAncestor, 0, true).rect()); // FIXME: Incorrect for CSS regions.
ASSERT(parentClipRect != PaintInfo::infiniteRect());
m_ancestorClippingLayer->setPosition(FloatPoint() + (parentClipRect.location() - graphicsLayerParentLocation));
m_ancestorClippingLayer->setSize(parentClipRect.size());
@@ -457,7 +457,7 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
}
m_graphicsLayer->setPosition(FloatPoint() + (relativeCompositingBounds.location() - graphicsLayerParentLocation));
- m_graphicsLayer->setOffsetFromRenderer(localCompositingBounds.location() - LayoutPoint());
+ m_graphicsLayer->setOffsetFromRenderer(localCompositingBounds.location() - IntPoint());
FloatSize oldSize = m_graphicsLayer->size();
FloatSize newSize = relativeCompositingBounds.size();
@@ -470,12 +470,12 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
}
// If we have a layer that clips children, position it.
- LayoutRect clippingBox;
+ IntRect clippingBox;
if (m_clippingLayer) {
clippingBox = clipBox(toRenderBox(renderer()));
m_clippingLayer->setPosition(FloatPoint() + (clippingBox.location() - localCompositingBounds.location()));
m_clippingLayer->setSize(clippingBox.size());
- m_clippingLayer->setOffsetFromRenderer(clippingBox.location() - LayoutPoint());
+ m_clippingLayer->setOffsetFromRenderer(clippingBox.location() - IntPoint());
}
if (m_maskLayer) {
@@ -488,10 +488,10 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
}
if (m_owningLayer->hasTransform()) {
- const LayoutRect borderBox = toRenderBox(renderer())->borderBoxRect();
+ const IntRect borderBox = pixelSnappedIntRect(toRenderBox(renderer())->borderBoxRect());
// Get layout bounds in the coords of compAncestor to match relativeCompositingBounds.
- LayoutRect layerBounds = LayoutRect(delta, borderBox.size());
+ IntRect layerBounds = IntRect(delta, borderBox.size());
// Update properties that depend on layer dimensions
FloatPoint3D transformOrigin = computeTransformOrigin(borderBox);
@@ -524,12 +524,12 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
if (m_foregroundLayer) {
FloatPoint foregroundPosition;
FloatSize foregroundSize = newSize;
- LayoutSize foregroundOffset = m_graphicsLayer->offsetFromRenderer();
+ IntSize foregroundOffset = m_graphicsLayer->offsetFromRenderer();
if (m_clippingLayer) {
// If we have a clipping layer (which clips descendants), then the foreground layer is a child of it,
// so that it gets correctly sorted with children. In that case, position relative to the clipping layer.
foregroundSize = FloatSize(clippingBox.size());
- foregroundOffset = clippingBox.location() - LayoutPoint();
+ foregroundOffset = clippingBox.location() - IntPoint();
}
m_foregroundLayer->setPosition(foregroundPosition);
@@ -1002,7 +1002,7 @@ void RenderLayerBacking::updateImageContents()
image->startAnimation();
}
-FloatPoint3D RenderLayerBacking::computeTransformOrigin(const LayoutRect& borderBox) const
+FloatPoint3D RenderLayerBacking::computeTransformOrigin(const IntRect& borderBox) const
{
RenderStyle* style = renderer()->style();
@@ -1014,7 +1014,7 @@ FloatPoint3D RenderLayerBacking::computeTransformOrigin(const LayoutRect& border
return origin;
}
-FloatPoint RenderLayerBacking::computePerspectiveOrigin(const LayoutRect& borderBox) const
+FloatPoint RenderLayerBacking::computePerspectiveOrigin(const IntRect& borderBox) const
{
RenderStyle* style = renderer()->style();
@@ -1029,26 +1029,26 @@ FloatPoint RenderLayerBacking::computePerspectiveOrigin(const LayoutRect& border
}
// Return the offset from the top-left of this compositing layer at which the renderer's contents are painted.
-LayoutSize RenderLayerBacking::contentOffsetInCompostingLayer() const
+IntSize RenderLayerBacking::contentOffsetInCompostingLayer() const
{
- return LayoutSize(-m_compositedBounds.x(), -m_compositedBounds.y());
+ return IntSize(-m_compositedBounds.x(), -m_compositedBounds.y());
}
-LayoutRect RenderLayerBacking::contentsBox() const
+IntRect RenderLayerBacking::contentsBox() const
{
if (!renderer()->isBox())
- return LayoutRect();
+ return IntRect();
- LayoutRect contentsRect;
+ IntRect contentsRect;
#if ENABLE(VIDEO)
if (renderer()->isVideo()) {
RenderVideo* videoRenderer = toRenderVideo(renderer());
contentsRect = videoRenderer->videoBox();
} else
#endif
- contentsRect = toRenderBox(renderer())->contentBoxRect();
+ contentsRect = pixelSnappedIntRect(toRenderBox(renderer())->contentBoxRect());
- LayoutSize contentOffset = contentOffsetInCompostingLayer();
+ IntSize contentOffset = contentOffsetInCompostingLayer();
contentsRect.move(contentOffset);
return contentsRect;
}
@@ -1077,29 +1077,29 @@ void RenderLayerBacking::setContentsNeedDisplay()
}
// r is in the coordinate space of the layer's render object
-void RenderLayerBacking::setContentsNeedDisplayInRect(const LayoutRect& r)
+void RenderLayerBacking::setContentsNeedDisplayInRect(const IntRect& r)
{
if (m_graphicsLayer && m_graphicsLayer->drawsContent()) {
- LayoutRect layerDirtyRect = r;
+ IntRect layerDirtyRect = r;
layerDirtyRect.move(-m_graphicsLayer->offsetFromRenderer());
m_graphicsLayer->setNeedsDisplayInRect(layerDirtyRect);
}
if (m_foregroundLayer && m_foregroundLayer->drawsContent()) {
- LayoutRect layerDirtyRect = r;
+ IntRect layerDirtyRect = r;
layerDirtyRect.move(-m_foregroundLayer->offsetFromRenderer());
m_foregroundLayer->setNeedsDisplayInRect(layerDirtyRect);
}
if (m_maskLayer && m_maskLayer->drawsContent()) {
- LayoutRect layerDirtyRect = r;
+ IntRect layerDirtyRect = r;
layerDirtyRect.move(-m_maskLayer->offsetFromRenderer());
m_maskLayer->setNeedsDisplayInRect(layerDirtyRect);
}
}
void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* context,
- const LayoutRect& paintDirtyRect, // In the coords of rootLayer.
+ const IntRect& paintDirtyRect, // In the coords of rootLayer.
PaintBehavior paintBehavior, GraphicsLayerPaintingPhase paintingPhase,
RenderObject* paintingRoot)
{
@@ -1124,28 +1124,28 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*
ASSERT(!m_owningLayer->m_usedTransparency);
}
-static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const LayoutRect& clip)
+static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
{
if (!scrollbar)
return;
context.save();
- const LayoutRect& scrollbarRect = scrollbar->frameRect();
+ const IntRect& scrollbarRect = scrollbar->frameRect();
context.translate(-scrollbarRect.x(), -scrollbarRect.y());
- LayoutRect transformedClip = clip;
+ IntRect transformedClip = clip;
transformedClip.moveBy(scrollbarRect.location());
scrollbar->paint(&context, transformedClip);
context.restore();
}
// Up-call from compositing layer drawing callback.
-void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const LayoutRect& clip)
+void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const IntRect& clip)
{
if (graphicsLayer == m_graphicsLayer.get() || graphicsLayer == m_foregroundLayer.get() || graphicsLayer == m_maskLayer.get()) {
- InspectorInstrumentationCookie cookie = InspectorInstrumentation::willPaint(m_owningLayer->renderer()->frame(), clip);
+ InspectorInstrumentationCookie cookie = InspectorInstrumentation::willPaint(m_owningLayer->renderer()->frame(), &context, clip);
// The dirtyRect is in the coords of the painting root.
- LayoutRect dirtyRect = compositedBounds();
+ IntRect dirtyRect = compositedBounds();
dirtyRect.intersect(clip);
// We have to use the same root as for hit testing, because both methods can compute and cache clipRects.
@@ -1157,13 +1157,13 @@ void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, Graph
} else if (graphicsLayer == layerForVerticalScrollbar()) {
paintScrollbar(m_owningLayer->verticalScrollbar(), context, clip);
} else if (graphicsLayer == layerForScrollCorner()) {
- const LayoutRect& scrollCornerAndResizer = m_owningLayer->scrollCornerAndResizerRect();
+ const IntRect& scrollCornerAndResizer = m_owningLayer->scrollCornerAndResizerRect();
context.save();
context.translate(-scrollCornerAndResizer.x(), -scrollCornerAndResizer.y());
- LayoutRect transformedClip = clip;
+ IntRect transformedClip = clip;
transformedClip.moveBy(scrollCornerAndResizer.location());
- m_owningLayer->paintScrollCorner(&context, LayoutPoint(), transformedClip);
- m_owningLayer->paintResizer(&context, LayoutPoint(), transformedClip);
+ m_owningLayer->paintScrollCorner(&context, IntPoint(), transformedClip);
+ m_owningLayer->paintResizer(&context, IntPoint(), transformedClip);
context.restore();
}
}
@@ -1197,12 +1197,20 @@ bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim
{
bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity);
bool hasTransform = renderer()->isBox() && keyframes.containsProperty(CSSPropertyWebkitTransform);
-
- if (!hasOpacity && !hasTransform)
+#if ENABLE(CSS_FILTERS)
+ bool hasFilter = keyframes.containsProperty(CSSPropertyWebkitFilter);
+#else
+ bool hasFilter = false;
+#endif
+
+ if (!hasOpacity && !hasTransform && !hasFilter)
return false;
KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
KeyframeValueList opacityVector(AnimatedPropertyOpacity);
+#if ENABLE(CSS_FILTERS)
+ KeyframeValueList filterVector(AnimatedPropertyWebkitFilter);
+#endif
size_t numKeyframes = keyframes.size();
for (size_t i = 0; i < numKeyframes; ++i) {
@@ -1222,22 +1230,41 @@ bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim
if ((hasOpacity && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyOpacity))
opacityVector.insert(new FloatAnimationValue(key, keyframeStyle->opacity(), tf));
+
+#if ENABLE(CSS_FILTERS)
+ if ((hasFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitFilter))
+ filterVector.insert(new FilterAnimationValue(key, &(keyframeStyle->filter()), tf));
+#endif
}
bool didAnimateTransform = false;
bool didAnimateOpacity = false;
+#if ENABLE(CSS_FILTERS)
+ bool didAnimateFilter = false;
+#endif
- if (hasTransform && m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->borderBoxRect().size(), anim, keyframes.animationName(), timeOffset)) {
+ if (hasTransform && m_graphicsLayer->addAnimation(transformVector, pixelSnappedIntRect(toRenderBox(renderer())->borderBoxRect()).size(), anim, keyframes.animationName(), timeOffset)) {
didAnimateTransform = true;
compositor()->didStartAcceleratedAnimation(CSSPropertyWebkitTransform);
}
- if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, LayoutSize(), anim, keyframes.animationName(), timeOffset)) {
+ if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, IntSize(), anim, keyframes.animationName(), timeOffset)) {
didAnimateOpacity = true;
compositor()->didStartAcceleratedAnimation(CSSPropertyOpacity);
}
+#if ENABLE(CSS_FILTERS)
+ if (hasFilter && m_graphicsLayer->addAnimation(filterVector, IntSize(), anim, keyframes.animationName(), timeOffset)) {
+ didAnimateFilter = true;
+ compositor()->didStartAcceleratedAnimation(CSSPropertyWebkitFilter);
+ }
+#endif
+
+#if ENABLE(CSS_FILTERS)
+ return didAnimateTransform || didAnimateOpacity || didAnimateFilter;
+#else
return didAnimateTransform || didAnimateOpacity;
+#endif
}
void RenderLayerBacking::animationPaused(double timeOffset, const String& animationName)
@@ -1254,6 +1281,10 @@ bool RenderLayerBacking::startTransition(double timeOffset, int property, const
{
bool didAnimateOpacity = false;
bool didAnimateTransform = false;
+#if ENABLE(CSS_FILTERS)
+ bool didAnimateFilter = false;
+#endif
+
ASSERT(property != cAnimateAll);
if (property == (int)CSSPropertyOpacity) {
@@ -1263,7 +1294,7 @@ bool RenderLayerBacking::startTransition(double timeOffset, int property, const
opacityVector.insert(new FloatAnimationValue(0, compositingOpacity(fromStyle->opacity())));
opacityVector.insert(new FloatAnimationValue(1, compositingOpacity(toStyle->opacity())));
// The boxSize param is only used for transform animations (which can only run on RenderBoxes), so we pass an empty size here.
- if (m_graphicsLayer->addAnimation(opacityVector, LayoutSize(), opacityAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyOpacity), timeOffset)) {
+ if (m_graphicsLayer->addAnimation(opacityVector, IntSize(), opacityAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyOpacity), timeOffset)) {
// To ensure that the correct opacity is visible when the animation ends, also set the final opacity.
updateLayerOpacity(toStyle);
didAnimateOpacity = true;
@@ -1277,21 +1308,46 @@ bool RenderLayerBacking::startTransition(double timeOffset, int property, const
KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
transformVector.insert(new TransformAnimationValue(0, &fromStyle->transform()));
transformVector.insert(new TransformAnimationValue(1, &toStyle->transform()));
- if (m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->borderBoxRect().size(), transformAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitTransform), timeOffset)) {
- // To ensure that the correct transform is visible when the animation ends, also set the final opacity.
+ if (m_graphicsLayer->addAnimation(transformVector, pixelSnappedIntRect(toRenderBox(renderer())->borderBoxRect()).size(), transformAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitTransform), timeOffset)) {
+ // To ensure that the correct transform is visible when the animation ends, also set the final transform.
updateLayerTransform(toStyle);
didAnimateTransform = true;
}
}
}
+#if ENABLE(CSS_FILTERS)
+ if (property == (int)CSSPropertyWebkitFilter && m_owningLayer->hasFilter()) {
+ const Animation* filterAnim = toStyle->transitionForProperty(CSSPropertyWebkitFilter);
+ if (filterAnim && !filterAnim->isEmptyOrZeroDuration()) {
+ KeyframeValueList filterVector(AnimatedPropertyWebkitFilter);
+ filterVector.insert(new FilterAnimationValue(0, &fromStyle->filter()));
+ filterVector.insert(new FilterAnimationValue(1, &toStyle->filter()));
+ if (m_graphicsLayer->addAnimation(filterVector, IntSize(), filterAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitFilter), timeOffset)) {
+ // To ensure that the correct filter is visible when the animation ends, also set the final filter.
+ updateLayerFilters(toStyle);
+ didAnimateFilter = true;
+ }
+ }
+ }
+#endif
+
if (didAnimateOpacity)
compositor()->didStartAcceleratedAnimation(CSSPropertyOpacity);
if (didAnimateTransform)
compositor()->didStartAcceleratedAnimation(CSSPropertyWebkitTransform);
+#if ENABLE(CSS_FILTERS)
+ if (didAnimateFilter)
+ compositor()->didStartAcceleratedAnimation(CSSPropertyWebkitFilter);
+#endif
+
+#if ENABLE(CSS_FILTERS)
+ return didAnimateOpacity || didAnimateTransform || didAnimateFilter;
+#else
return didAnimateOpacity || didAnimateTransform;
+#endif
}
void RenderLayerBacking::transitionPaused(double timeOffset, int property)
@@ -1330,12 +1386,12 @@ void RenderLayerBacking::resumeAnimations()
m_graphicsLayer->resumeAnimations();
}
-LayoutRect RenderLayerBacking::compositedBounds() const
+IntRect RenderLayerBacking::compositedBounds() const
{
return m_compositedBounds;
}
-void RenderLayerBacking::setCompositedBounds(const LayoutRect& bounds)
+void RenderLayerBacking::setCompositedBounds(const IntRect& bounds)
{
m_compositedBounds = bounds;
@@ -1353,6 +1409,13 @@ int RenderLayerBacking::graphicsLayerToCSSProperty(AnimatedPropertyID property)
case AnimatedPropertyBackgroundColor:
cssProperty = CSSPropertyBackgroundColor;
break;
+ case AnimatedPropertyWebkitFilter:
+#if ENABLE(CSS_FILTERS)
+ cssProperty = CSSPropertyWebkitFilter;
+#else
+ ASSERT_NOT_REACHED();
+#endif
+ break;
case AnimatedPropertyInvalid:
ASSERT_NOT_REACHED();
}
@@ -1368,6 +1431,10 @@ AnimatedPropertyID RenderLayerBacking::cssToGraphicsLayerProperty(int cssPropert
return AnimatedPropertyOpacity;
case CSSPropertyBackgroundColor:
return AnimatedPropertyBackgroundColor;
+#if ENABLE(CSS_FILTERS)
+ case CSSPropertyWebkitFilter:
+ return AnimatedPropertyWebkitFilter;
+#endif
// It's fine if we see other css properties here; they are just not accelerated.
}
return AnimatedPropertyInvalid;
diff --git a/Source/WebCore/rendering/RenderLayerBacking.h b/Source/WebCore/rendering/RenderLayerBacking.h
index b2d481c57..e1fafc0ac 100644
--- a/Source/WebCore/rendering/RenderLayerBacking.h
+++ b/Source/WebCore/rendering/RenderLayerBacking.h
@@ -99,7 +99,7 @@ public:
void setContentsNeedDisplay();
// r is in the coordinate space of the layer's render object
- void setContentsNeedDisplayInRect(const LayoutRect&);
+ void setContentsNeedDisplayInRect(const IntRect&);
// Notification from the renderer that its content changed.
void contentChanged(RenderLayer::ContentChangeType);
@@ -116,8 +116,8 @@ public:
void suspendAnimations(double time = 0);
void resumeAnimations();
- LayoutRect compositedBounds() const;
- void setCompositedBounds(const LayoutRect&);
+ IntRect compositedBounds() const;
+ void setCompositedBounds(const IntRect&);
void updateCompositedBounds();
void updateAfterWidgetResize();
@@ -127,7 +127,7 @@ public:
virtual void notifyAnimationStarted(const GraphicsLayer*, double startTime);
virtual void notifySyncRequired(const GraphicsLayer*);
- virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const LayoutRect& clip);
+ virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& clip);
virtual float deviceScaleFactor() const;
virtual float pageScaleFactor() const;
@@ -136,7 +136,7 @@ public:
virtual bool showDebugBorders(const GraphicsLayer*) const;
virtual bool showRepaintCounter(const GraphicsLayer*) const;
- LayoutRect contentsBox() const;
+ IntRect contentsBox() const;
// For informative purposes only.
CompositingLayerType compositingLayerType() const;
@@ -169,11 +169,11 @@ private:
GraphicsLayerPaintingPhase paintingPhaseForPrimaryLayer() const;
- LayoutSize contentOffsetInCompostingLayer() const;
+ IntSize contentOffsetInCompostingLayer() const;
// Result is transform origin in pixels.
- FloatPoint3D computeTransformOrigin(const LayoutRect& borderBox) const;
+ FloatPoint3D computeTransformOrigin(const IntRect& borderBox) const;
// Result is perspective origin in pixels.
- FloatPoint computePerspectiveOrigin(const LayoutRect& borderBox) const;
+ FloatPoint computePerspectiveOrigin(const IntRect& borderBox) const;
void updateLayerOpacity(const RenderStyle*);
void updateLayerTransform(const RenderStyle*);
@@ -200,7 +200,7 @@ private:
bool containsNonEmptyRenderers() const;
bool hasVisibleNonCompositingDescendantLayers() const;
- void paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*, const LayoutRect& paintDirtyRect, PaintBehavior, GraphicsLayerPaintingPhase, RenderObject* paintingRoot);
+ void paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*, const IntRect& paintDirtyRect, PaintBehavior, GraphicsLayerPaintingPhase, RenderObject* paintingRoot);
static int graphicsLayerToCSSProperty(AnimatedPropertyID);
static AnimatedPropertyID cssToGraphicsLayerProperty(int);
@@ -221,7 +221,7 @@ private:
OwnPtr<GraphicsLayer> m_layerForVerticalScrollbar;
OwnPtr<GraphicsLayer> m_layerForScrollCorner;
- LayoutRect m_compositedBounds;
+ IntRect m_compositedBounds;
bool m_artificiallyInflatedBounds; // bounds had to be made non-zero to make transform-origin work
bool m_isMainFrameRenderViewLayer;
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp
index 5c0ab779f..75a280c95 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp
@@ -51,16 +51,13 @@
#include "RenderVideo.h"
#include "RenderView.h"
#include "ScrollbarTheme.h"
+#include "ScrollingCoordinator.h"
#include "Settings.h"
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
#include "HTMLMediaElement.h"
#endif
-#if ENABLE(THREADED_SCROLLING)
-#include "ScrollingCoordinator.h"
-#endif
-
#if PROFILE_LAYER_REBUILD
#include <wtf/CurrentTime.h>
#endif
@@ -456,10 +453,10 @@ void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer)
// The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant
// RenderLayers that are rendered by the composited RenderLayer.
-LayoutRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer)
+IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer)
{
if (!canBeComposited(layer))
- return LayoutRect();
+ return IntRect();
LayoutRect boundingBoxRect = layer->localBoundingBox();
if (layer->renderer()->isRoot()) {
@@ -467,8 +464,8 @@ LayoutRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* l
// then it has to be big enough to cover the viewport in order to display the background. This is akin
// to the code in RenderBox::paintRootBoxFillLayers().
if (m_renderView->frameView()) {
- int rw = m_renderView->frameView()->contentsWidth();
- int rh = m_renderView->frameView()->contentsHeight();
+ LayoutUnit rw = m_renderView->frameView()->contentsWidth();
+ LayoutUnit rh = m_renderView->frameView()->contentsHeight();
boundingBoxRect.setWidth(max(boundingBoxRect.width(), rw - boundingBoxRect.x()));
boundingBoxRect.setHeight(max(boundingBoxRect.height(), rh - boundingBoxRect.y()));
@@ -481,7 +478,7 @@ LayoutRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* l
LayoutPoint ancestorRelOffset;
layer->convertToLayerCoords(ancestorLayer, ancestorRelOffset);
boundingBoxRect.moveBy(ancestorRelOffset);
- return boundingBoxRect;
+ return pixelSnappedIntRect(boundingBoxRect);
}
if (RenderLayer* reflection = layer->reflectionLayer()) {
@@ -536,7 +533,7 @@ LayoutRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* l
layer->convertToLayerCoords(ancestorLayer, ancestorRelOffset);
unionBounds.moveBy(ancestorRelOffset);
- return unionBounds;
+ return pixelSnappedIntRect(unionBounds);
}
void RenderLayerCompositor::layerWasAdded(RenderLayer* /*parent*/, RenderLayer* /*child*/)
@@ -582,7 +579,7 @@ RenderLayer* RenderLayerCompositor::enclosingNonStackingClippingLayer(const Rend
return 0;
}
-void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer* layer, LayoutRect& layerBounds, bool& boundsComputed)
+void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer* layer, IntRect& layerBounds, bool& boundsComputed)
{
if (layer->isRootLayer())
return;
@@ -591,11 +588,11 @@ void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer*
layerBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox();
// Empty rects never intersect, but we need them to for the purposes of overlap testing.
if (layerBounds.isEmpty())
- layerBounds.setSize(LayoutSize(1, 1));
+ layerBounds.setSize(IntSize(1, 1));
boundsComputed = true;
}
- LayoutRect clipRect = layer->backgroundClipRect(rootRenderLayer(), 0, true).rect(); // FIXME: Incorrect for CSS regions.
+ IntRect clipRect = pixelSnappedIntRect(layer->backgroundClipRect(rootRenderLayer(), 0, true).rect()); // FIXME: Incorrect for CSS regions.
clipRect.scale(pageScaleFactor());
clipRect.intersect(layerBounds);
overlapMap.add(layer, clipRect);
@@ -606,7 +603,7 @@ void RenderLayerCompositor::addToOverlapMapRecursive(OverlapMap& overlapMap, Ren
if (!canBeComposited(layer) || overlapMap.contains(layer))
return;
- LayoutRect bounds;
+ IntRect bounds;
bool haveComputedBounds = false;
addToOverlapMap(overlapMap, layer, bounds, haveComputedBounds);
@@ -640,11 +637,11 @@ void RenderLayerCompositor::addToOverlapMapRecursive(OverlapMap& overlapMap, Ren
}
}
-bool RenderLayerCompositor::overlapsCompositedLayers(OverlapMap& overlapMap, const LayoutRect& layerBounds)
+bool RenderLayerCompositor::overlapsCompositedLayers(OverlapMap& overlapMap, const IntRect& layerBounds)
{
RenderLayerCompositor::OverlapMap::const_iterator end = overlapMap.end();
for (RenderLayerCompositor::OverlapMap::const_iterator it = overlapMap.begin(); it != end; ++it) {
- const LayoutRect& bounds = it->second;
+ const IntRect& bounds = it->second;
if (layerBounds.intersects(bounds))
return true;
}
@@ -673,13 +670,13 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
bool mustOverlapCompositedLayers = compositingState.m_subtreeIsCompositing;
bool haveComputedBounds = false;
- LayoutRect absBounds;
+ IntRect absBounds;
if (overlapMap && !overlapMap->isEmpty()) {
// If we're testing for overlap, we only need to composite if we overlap something that is already composited.
absBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox();
// Empty rects never intersect, but we need them to for the purposes of overlap testing.
if (absBounds.isEmpty())
- absBounds.setSize(LayoutSize(1, 1));
+ absBounds.setSize(IntSize(1, 1));
haveComputedBounds = true;
mustOverlapCompositedLayers = overlapsCompositedLayers(*overlapMap, absBounds);
}
@@ -953,7 +950,7 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, Vect
}
}
-void RenderLayerCompositor::frameViewDidChangeLocation(const LayoutPoint& contentsOffset)
+void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset)
{
if (m_overflowControlsHostLayer)
m_overflowControlsHostLayer->setPosition(contentsOffset);
@@ -978,13 +975,22 @@ void RenderLayerCompositor::frameViewDidChangeSize()
void RenderLayerCompositor::frameViewDidScroll()
{
FrameView* frameView = m_renderView->frameView();
- LayoutPoint scrollPosition = frameView->scrollPosition();
+ IntPoint scrollPosition = frameView->scrollPosition();
if (RenderLayerBacking* backing = rootRenderLayer()->backing())
backing->graphicsLayer()->visibleRectChanged();
- if (m_scrollLayer)
- m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y()));
+ if (!m_scrollLayer)
+ return;
+
+ // If there's a scrolling coordinator that manages scrolling for this frame view,
+ // it will also manage updating the scroll layer position.
+ if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
+ if (scrollingCoordinator->coordinatesScrollingForFrameView(frameView))
+ return;
+ }
+
+ m_scrollLayer->setPosition(FloatPoint(-scrollPosition.x(), -scrollPosition.y()));
}
String RenderLayerCompositor::layerTreeAsText(bool showDebugInfo)
@@ -1126,12 +1132,12 @@ void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer* com
}
-void RenderLayerCompositor::repaintCompositedLayersAbsoluteRect(const LayoutRect& absRect)
+void RenderLayerCompositor::repaintCompositedLayersAbsoluteRect(const IntRect& absRect)
{
recursiveRepaintLayerRect(rootRenderLayer(), absRect);
}
-void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const LayoutRect& rect)
+void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const IntRect& rect)
{
// FIXME: This method does not work correctly with transforms.
if (layer->isComposited())
@@ -1142,8 +1148,8 @@ void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const
size_t listSize = negZOrderList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = negZOrderList->at(i);
- LayoutRect childRect(rect);
- curLayer->convertToLayerCoords(layer, childRect);
+ IntRect childRect(rect);
+ curLayer->convertToPixelSnappedLayerCoords(layer, childRect);
recursiveRepaintLayerRect(curLayer, childRect);
}
}
@@ -1152,8 +1158,8 @@ void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const
size_t listSize = posZOrderList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = posZOrderList->at(i);
- LayoutRect childRect(rect);
- curLayer->convertToLayerCoords(layer, childRect);
+ IntRect childRect(rect);
+ curLayer->convertToPixelSnappedLayerCoords(layer, childRect);
recursiveRepaintLayerRect(curLayer, childRect);
}
}
@@ -1162,8 +1168,8 @@ void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const
size_t listSize = normalFlowList->size();
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = normalFlowList->at(i);
- LayoutRect childRect(rect);
- curLayer->convertToLayerCoords(layer, childRect);
+ IntRect childRect(rect);
+ curLayer->convertToPixelSnappedLayerCoords(layer, childRect);
recursiveRepaintLayerRect(curLayer, childRect);
}
}
@@ -1223,7 +1229,7 @@ void RenderLayerCompositor::clearBackingForAllLayers()
void RenderLayerCompositor::updateRootLayerPosition()
{
if (m_rootContentLayer) {
- const LayoutRect& documentRect = m_renderView->documentRect();
+ const IntRect& documentRect = m_renderView->documentRect();
m_rootContentLayer->setSize(documentRect.size());
m_rootContentLayer->setPosition(documentRect.location());
}
@@ -1463,7 +1469,7 @@ bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer)
return pluginRenderer->hasLayer() && pluginRenderer->layer()->isComposited();
// Don't go into compositing mode if height or width are zero, or size is 1x1.
- LayoutRect contentBox = pluginRenderer->contentBoxRect();
+ IntRect contentBox = pixelSnappedIntRect(pluginRenderer->contentBoxRect());
return contentBox.height() * contentBox.width() > 1;
}
@@ -1488,7 +1494,7 @@ bool RenderLayerCompositor::requiresCompositingForFrame(RenderObject* renderer)
return frameRenderer->hasLayer() && frameRenderer->layer()->isComposited();
// Don't go into compositing mode if height or width are zero.
- LayoutRect contentBox = frameRenderer->contentBoxRect();
+ IntRect contentBox = pixelSnappedIntRect(frameRenderer->contentBoxRect());
return contentBox.height() * contentBox.width() > 0;
}
@@ -1556,6 +1562,11 @@ bool RenderLayerCompositor::requiresCompositingForPosition(RenderObject* rendere
if (container != m_renderView)
return false;
+ // Fixed position elements that are invisible in the current view don't get their own layer.
+ FrameView* frameView = m_renderView->frameView();
+ if (frameView && !layer->absoluteBoundingBox().intersects(LayoutRect(frameView->scrollXForFixedPosition(), frameView->scrollYForFixedPosition(), frameView->layoutWidth(), frameView->layoutHeight())))
+ return false;
+
return true;
}
@@ -1592,31 +1603,31 @@ bool RenderLayerCompositor::requiresScrollLayer(RootLayerAttachment attachment)
|| attachment == RootLayerAttachedViaEnclosingFrame; // a composited frame on Mac
}
-static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const LayoutRect& clip)
+static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
{
if (!scrollbar)
return;
context.save();
- const LayoutRect& scrollbarRect = scrollbar->frameRect();
+ const IntRect& scrollbarRect = scrollbar->frameRect();
context.translate(-scrollbarRect.x(), -scrollbarRect.y());
- LayoutRect transformedClip = clip;
+ IntRect transformedClip = clip;
transformedClip.moveBy(scrollbarRect.location());
scrollbar->paint(&context, transformedClip);
context.restore();
}
-void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const LayoutRect& clip)
+void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip)
{
if (graphicsLayer == layerForHorizontalScrollbar())
paintScrollbar(m_renderView->frameView()->horizontalScrollbar(), context, clip);
else if (graphicsLayer == layerForVerticalScrollbar())
paintScrollbar(m_renderView->frameView()->verticalScrollbar(), context, clip);
else if (graphicsLayer == layerForScrollCorner()) {
- const LayoutRect& scrollCorner = m_renderView->frameView()->scrollCornerRect();
+ const IntRect& scrollCorner = m_renderView->frameView()->scrollCornerRect();
context.save();
context.translate(-scrollCorner.x(), -scrollCorner.y());
- LayoutRect transformedClip = clip;
+ IntRect transformedClip = clip;
transformedClip.moveBy(scrollCorner.location());
m_renderView->frameView()->paintScrollCorner(&context, transformedClip);
context.restore();
@@ -1628,6 +1639,23 @@ void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, Gr
}
}
+void RenderLayerCompositor::documentBackgroundColorDidChange()
+{
+ RenderLayerBacking* backing = rootRenderLayer()->backing();
+ if (!backing)
+ return;
+
+ GraphicsLayer* graphicsLayer = backing->graphicsLayer();
+ if (!graphicsLayer->client()->shouldUseTileCache(graphicsLayer))
+ return;
+
+ Color backgroundColor = m_renderView->frameView()->documentBackgroundColor();
+ if (!backgroundColor.isValid() || backgroundColor.hasAlpha())
+ backgroundColor = Color::white;
+
+ graphicsLayer->setBackgroundColor(backgroundColor);
+}
+
bool RenderLayerCompositor::showDebugBorders(const GraphicsLayer* layer) const
{
if (layer == m_layerForHorizontalScrollbar || layer == m_layerForVerticalScrollbar || layer == m_layerForScrollCorner)
@@ -1682,12 +1710,11 @@ static bool shouldCompositeOverflowControls(FrameView* view)
if (view->platformWidget())
return false;
-#if ENABLE(THREADED_SCROLLING)
if (Page* page = view->frame()->page()) {
if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
- return scrollingCoordinator->coordinatesScrollingForFrameView(view);
+ if (scrollingCoordinator->coordinatesScrollingForFrameView(view))
+ return true;
}
-#endif
#if !PLATFORM(CHROMIUM)
if (!view->hasOverlayScrollbars())
@@ -1722,10 +1749,8 @@ bool RenderLayerCompositor::requiresOverhangAreasLayer() const
return false;
// We do want a layer if we have a scrolling coordinator.
-#if ENABLE(THREADED_SCROLLING)
if (scrollingCoordinator())
return true;
-#endif
// Chromium always wants a layer.
#if PLATFORM(CHROMIUM)
@@ -1741,7 +1766,7 @@ bool RenderLayerCompositor::requiresContentShadowLayer() const
if (m_renderView->document()->ownerElement())
return false;
-#if PLATFORM(MAC) && ENABLE(THREADED_SCROLLING)
+#if PLATFORM(MAC)
// On Mac, we want a content shadow layer if we have a scrolling coordinator.
if (scrollingCoordinator())
return true;
@@ -1800,19 +1825,15 @@ void RenderLayerCompositor::updateOverflowControlsLayers()
#endif
m_overflowControlsHostLayer->addChild(m_layerForHorizontalScrollbar.get());
-#if ENABLE(THREADED_SCROLLING)
if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
scrollingCoordinator->frameViewHorizontalScrollbarLayerDidChange(m_renderView->frameView(), m_layerForHorizontalScrollbar.get());
-#endif
}
} else if (m_layerForHorizontalScrollbar) {
m_layerForHorizontalScrollbar->removeFromParent();
m_layerForHorizontalScrollbar = nullptr;
-#if ENABLE(THREADED_SCROLLING)
if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
scrollingCoordinator->frameViewHorizontalScrollbarLayerDidChange(m_renderView->frameView(), 0);
-#endif
}
if (requiresVerticalScrollbarLayer()) {
@@ -1823,19 +1844,15 @@ void RenderLayerCompositor::updateOverflowControlsLayers()
#endif
m_overflowControlsHostLayer->addChild(m_layerForVerticalScrollbar.get());
-#if ENABLE(THREADED_SCROLLING)
if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
scrollingCoordinator->frameViewVerticalScrollbarLayerDidChange(m_renderView->frameView(), m_layerForVerticalScrollbar.get());
-#endif
}
} else if (m_layerForVerticalScrollbar) {
m_layerForVerticalScrollbar->removeFromParent();
m_layerForVerticalScrollbar = nullptr;
-#if ENABLE(THREADED_SCROLLING)
if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
scrollingCoordinator->frameViewVerticalScrollbarLayerDidChange(m_renderView->frameView(), 0);
-#endif
}
if (requiresScrollCornerLayer()) {
@@ -1865,7 +1882,8 @@ void RenderLayerCompositor::ensureRootLayer()
#ifndef NDEBUG
m_rootContentLayer->setName("content root");
#endif
- m_rootContentLayer->setSize(FloatSize(m_renderView->maxXLayoutOverflow(), m_renderView->maxYLayoutOverflow()));
+ IntRect overflowRect = m_renderView->pixelSnappedLayoutOverflowRect();
+ m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.maxY()));
m_rootContentLayer->setPosition(FloatPoint());
// Need to clip to prevent transformed content showing outside this frame
@@ -1902,11 +1920,6 @@ void RenderLayerCompositor::ensureRootLayer()
frameViewDidChangeSize();
frameViewDidScroll();
-
-#if ENABLE(THREADED_SCROLLING)
- if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
- scrollingCoordinator->frameViewScrollLayerDidChange(m_renderView->frameView(), m_scrollLayer.get());
-#endif
}
} else {
if (m_overflowControlsHostLayer) {
@@ -1941,14 +1954,14 @@ void RenderLayerCompositor::destroyRootLayer()
m_layerForHorizontalScrollbar->removeFromParent();
m_layerForHorizontalScrollbar = nullptr;
if (Scrollbar* horizontalScrollbar = m_renderView->frameView()->verticalScrollbar())
- m_renderView->frameView()->invalidateScrollbar(horizontalScrollbar, LayoutRect(LayoutPoint(0, 0), horizontalScrollbar->frameRect().size()));
+ m_renderView->frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size()));
}
if (m_layerForVerticalScrollbar) {
m_layerForVerticalScrollbar->removeFromParent();
m_layerForVerticalScrollbar = nullptr;
if (Scrollbar* verticalScrollbar = m_renderView->frameView()->verticalScrollbar())
- m_renderView->frameView()->invalidateScrollbar(verticalScrollbar, LayoutRect(LayoutPoint(0, 0), verticalScrollbar->frameRect().size()));
+ m_renderView->frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size()));
}
if (m_layerForScrollCorner) {
@@ -1990,7 +2003,10 @@ void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment)
break;
}
}
-
+
+ if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
+ scrollingCoordinator->frameViewRootLayerDidChange(m_renderView->frameView());
+
m_rootLayerAttachment = attachment;
rootLayerAttachmentChanged();
}
@@ -2116,7 +2132,6 @@ void RenderLayerCompositor::deviceOrPageScaleFactorChanged()
rootLayer->noteDeviceOrPageScaleFactorChangedIncludingDescendants();
}
-#if ENABLE(THREADED_SCROLLING)
ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const
{
if (Frame* frame = m_renderView->frameView()->frame()) {
@@ -2126,7 +2141,6 @@ ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const
return 0;
}
-#endif
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.h b/Source/WebCore/rendering/RenderLayerCompositor.h
index 00518f3df..86aea07a6 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.h
+++ b/Source/WebCore/rendering/RenderLayerCompositor.h
@@ -37,12 +37,10 @@ namespace WebCore {
class GraphicsLayer;
class RenderEmbeddedObject;
class RenderPart;
+class ScrollingCoordinator;
#if ENABLE(VIDEO)
class RenderVideo;
#endif
-#if ENABLE(THREADED_SCROLLING)
-class ScrollingCoordinator;
-#endif
enum CompositingUpdateType {
CompositingUpdateAfterLayoutOrStyleChange,
@@ -121,7 +119,7 @@ public:
bool needsContentsCompositingLayer(const RenderLayer*) const;
// Return the bounding box required for compositing layer and its childern, relative to ancestorLayer.
// If layerBoundingBox is not 0, on return it contains the bounding box of this layer only.
- LayoutRect calculateCompositedBounds(const RenderLayer*, const RenderLayer* ancestorLayer);
+ IntRect calculateCompositedBounds(const RenderLayer*, const RenderLayer* ancestorLayer);
// Repaint the appropriate layers when the given RenderLayer starts or stops being composited.
void repaintOnCompositingChange(RenderLayer*);
@@ -134,7 +132,7 @@ public:
RenderLayer* enclosingNonStackingClippingLayer(const RenderLayer* layer) const;
// Repaint parts of all composited layers that intersect the given absolute rectangle.
- void repaintCompositedLayersAbsoluteRect(const LayoutRect&);
+ void repaintCompositedLayersAbsoluteRect(const IntRect&);
RenderLayer* rootRenderLayer() const;
GraphicsLayer* rootGraphicsLayer() const;
@@ -183,7 +181,7 @@ public:
static bool parentFrameContentLayers(RenderPart*);
// Update the geometry of the layers used for clipping and scrolling in frames.
- void frameViewDidChangeLocation(const LayoutPoint& contentsOffset);
+ void frameViewDidChangeLocation(const IntPoint& contentsOffset);
void frameViewDidChangeSize();
void frameViewDidScroll();
@@ -209,11 +207,13 @@ public:
GraphicsLayer* layerForOverhangAreas() const { return m_layerForOverhangAreas.get(); }
#endif
+ void documentBackgroundColorDidChange();
+
private:
// GraphicsLayerClient Implementation
virtual void notifyAnimationStarted(const GraphicsLayer*, double) { }
virtual void notifySyncRequired(const GraphicsLayer*) { scheduleLayerFlush(); }
- virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const LayoutRect&);
+ virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect&);
virtual bool showDebugBorders(const GraphicsLayer*) const;
virtual bool showRepaintCounter(const GraphicsLayer*) const;
@@ -231,12 +231,12 @@ private:
void clearBackingForLayerIncludingDescendants(RenderLayer*);
// Repaint the given rect (which is layer's coords), and regions of child layers that intersect that rect.
- void recursiveRepaintLayerRect(RenderLayer*, const LayoutRect&);
+ void recursiveRepaintLayerRect(RenderLayer*, const IntRect&);
- typedef HashMap<RenderLayer*, LayoutRect> OverlapMap;
- void addToOverlapMap(OverlapMap&, RenderLayer*, LayoutRect& layerBounds, bool& boundsComputed);
+ typedef HashMap<RenderLayer*, IntRect> OverlapMap;
+ void addToOverlapMap(OverlapMap&, RenderLayer*, IntRect& layerBounds, bool& boundsComputed);
void addToOverlapMapRecursive(OverlapMap&, RenderLayer*);
- static bool overlapsCompositedLayers(OverlapMap&, const LayoutRect& layerBounds);
+ static bool overlapsCompositedLayers(OverlapMap&, const IntRect& layerBounds);
void updateCompositingLayersTimerFired(Timer<RenderLayerCompositor>*);
@@ -272,6 +272,8 @@ private:
bool isFlushingLayers() const { return m_flushingLayers; }
+ ScrollingCoordinator* scrollingCoordinator() const;
+
// Whether a running transition or animation enforces the need for a compositing layer.
bool requiresCompositingForAnimation(RenderObject*) const;
bool requiresCompositingForTransform(RenderObject*) const;
@@ -294,10 +296,6 @@ private:
bool requiresContentShadowLayer() const;
#endif
-#if ENABLE(THREADED_SCROLLING)
- ScrollingCoordinator* scrollingCoordinator() const;
-#endif
-
private:
RenderView* m_renderView;
OwnPtr<GraphicsLayer> m_rootContentLayer;
diff --git a/Source/WebCore/rendering/RenderListBox.cpp b/Source/WebCore/rendering/RenderListBox.cpp
index d47a1801e..68ae283e3 100644
--- a/Source/WebCore/rendering/RenderListBox.cpp
+++ b/Source/WebCore/rendering/RenderListBox.cpp
@@ -255,7 +255,7 @@ void RenderListBox::computeLogicalHeight()
m_vBar->setSteps(1, max(1, numVisibleItems() - 1), itemHeight);
m_vBar->setProportion(numVisibleItems(), numItems());
if (!enabled) {
- scrollToYOffsetWithoutAnimation(0);
+ scrollToOffsetWithoutAnimation(VerticalScrollbar, 0);
m_indexOffset = 0;
}
}
@@ -473,7 +473,7 @@ int RenderListBox::listIndexAtOffset(const LayoutSize& offset)
if (offset.height() < borderTop() + paddingTop() || offset.height() > height() - paddingBottom() - borderBottom())
return -1;
- LayoutUnit scrollbarWidth = m_vBar ? m_vBar->width() : LayoutUnit(0);
+ int scrollbarWidth = m_vBar ? m_vBar->width() : 0;
if (offset.width() < borderLeft() + paddingLeft() || offset.width() > width() - borderRight() - paddingRight() - scrollbarWidth)
return -1;
@@ -579,7 +579,7 @@ bool RenderListBox::scrollToRevealElementAtListIndex(int index)
else
newOffset = index - numVisibleItems() + 1;
- ScrollableArea::scrollToYOffsetWithoutAnimation(newOffset);
+ scrollToOffsetWithoutAnimation(VerticalScrollbar, newOffset);
return true;
}
@@ -638,7 +638,7 @@ LayoutUnit RenderListBox::itemHeight() const
int RenderListBox::verticalScrollbarWidth() const
{
- return m_vBar && !m_vBar->isOverlayScrollbar() ? m_vBar->width() : LayoutUnit(0);
+ return m_vBar && !m_vBar->isOverlayScrollbar() ? m_vBar->width() : 0;
}
// FIXME: We ignore padding in the vertical direction as far as these values are concerned, since that's
@@ -675,7 +675,7 @@ void RenderListBox::setScrollTop(int newTop)
if (index < 0 || index >= numItems() || index == m_indexOffset)
return;
- ScrollableArea::scrollToYOffsetWithoutAnimation(index);
+ scrollToOffsetWithoutAnimation(VerticalScrollbar, index);
}
bool RenderListBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
diff --git a/Source/WebCore/rendering/RenderListBox.h b/Source/WebCore/rendering/RenderListBox.h
index e63e00386..407fa5247 100644
--- a/Source/WebCore/rendering/RenderListBox.h
+++ b/Source/WebCore/rendering/RenderListBox.h
@@ -62,8 +62,6 @@ private:
virtual void updateFromElement();
- virtual bool canHaveChildren() const { return false; }
-
virtual bool hasControlClip() const { return true; }
virtual void paintObject(PaintInfo&, const LayoutPoint&);
virtual LayoutRect controlClipRect(const LayoutPoint&) const;
diff --git a/Source/WebCore/rendering/RenderListItem.cpp b/Source/WebCore/rendering/RenderListItem.cpp
index a5b5b94e8..883218d4f 100644
--- a/Source/WebCore/rendering/RenderListItem.cpp
+++ b/Source/WebCore/rendering/RenderListItem.cpp
@@ -247,6 +247,9 @@ void RenderListItem::updateMarkerLocation()
LayoutStateDisabler layoutStateDisabler(view());
updateFirstLetter();
m_marker->remove();
+ // If markerPar is an anonymous block that will lose all its children, destroy it
+ if (markerPar && (markerPar != lineBoxParent) && markerPar->isAnonymousBlock() && !(toRenderBlock(markerPar)->firstChild()))
+ markerPar->destroy();
if (!lineBoxParent)
lineBoxParent = this;
lineBoxParent->addChild(m_marker, firstNonMarkerChild(lineBoxParent));
diff --git a/Source/WebCore/rendering/RenderListMarker.cpp b/Source/WebCore/rendering/RenderListMarker.cpp
index e7f85283a..fe193987c 100644
--- a/Source/WebCore/rendering/RenderListMarker.cpp
+++ b/Source/WebCore/rendering/RenderListMarker.cpp
@@ -1110,7 +1110,7 @@ void RenderListMarker::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffse
if (style()->visibility() != VISIBLE)
return;
- LayoutPoint boxOrigin(paintOffset + location());
+ IntPoint boxOrigin(paintOffset + location());
LayoutRect overflowRect(visualOverflowRect());
overflowRect.moveBy(boxOrigin);
overflowRect.inflate(maximalOutlineSize(paintInfo.phase));
diff --git a/Source/WebCore/rendering/RenderMarquee.cpp b/Source/WebCore/rendering/RenderMarquee.cpp
index ad5892cc6..fe5dbaa22 100644
--- a/Source/WebCore/rendering/RenderMarquee.cpp
+++ b/Source/WebCore/rendering/RenderMarquee.cpp
@@ -125,13 +125,13 @@ int RenderMarquee::computePosition(EMarqueeDirection dir, bool stopAtContentEdge
}
if (dir == MRIGHT) {
if (stopAtContentEdge)
- return max(0, ltr ? (contentWidth - clientWidth) : (clientWidth - contentWidth));
+ return max(zeroLayoutUnit, ltr ? (contentWidth - clientWidth) : (clientWidth - contentWidth));
else
return ltr ? contentWidth : clientWidth;
}
else {
if (stopAtContentEdge)
- return min(0, ltr ? (contentWidth - clientWidth) : (clientWidth - contentWidth));
+ return min(zeroLayoutUnit, ltr ? (contentWidth - clientWidth) : (clientWidth - contentWidth));
else
return ltr ? -clientWidth : -contentWidth;
}
diff --git a/Source/WebCore/rendering/RenderMedia.h b/Source/WebCore/rendering/RenderMedia.h
index 78e36c4ce..54e625af3 100644
--- a/Source/WebCore/rendering/RenderMedia.h
+++ b/Source/WebCore/rendering/RenderMedia.h
@@ -51,6 +51,7 @@ protected:
private:
virtual RenderObjectChildList* virtualChildren() { return children(); }
virtual const RenderObjectChildList* virtualChildren() const { return children(); }
+ virtual bool canHaveChildren() const { return true; }
virtual const char* renderName() const { return "RenderMedia"; }
virtual bool isMedia() const { return true; }
diff --git a/Source/WebCore/rendering/RenderMenuList.h b/Source/WebCore/rendering/RenderMenuList.h
index b6f44364f..27872eba2 100644
--- a/Source/WebCore/rendering/RenderMenuList.h
+++ b/Source/WebCore/rendering/RenderMenuList.h
@@ -62,12 +62,12 @@ private:
virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
virtual void removeChild(RenderObject*);
virtual bool createsAnonymousWrapper() const { return true; }
- virtual bool canHaveChildren() const { return false; }
virtual void updateFromElement();
- virtual bool hasControlClip() const { return true; }
virtual LayoutRect controlClipRect(const LayoutPoint&) const;
+ virtual bool hasControlClip() const { return true; }
+ virtual RenderText* buttonText() const OVERRIDE { return m_buttonText; }
virtual const char* renderName() const { return "RenderMenuList"; }
diff --git a/Source/WebCore/rendering/RenderMeter.h b/Source/WebCore/rendering/RenderMeter.h
index 6eb171761..c4deb12b2 100644
--- a/Source/WebCore/rendering/RenderMeter.h
+++ b/Source/WebCore/rendering/RenderMeter.h
@@ -42,7 +42,6 @@ private:
virtual const char* renderName() const { return "RenderMeter"; }
virtual bool isMeter() const { return true; }
virtual bool requiresForcedStyleRecalcPropagation() const { return true; }
- virtual bool canHaveChildren() const { return false; }
virtual void updateFromElement();
double valueRatio() const;
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())
diff --git a/Source/WebCore/rendering/RenderObject.h b/Source/WebCore/rendering/RenderObject.h
index 1bcda46aa..ac1bfc76d 100644
--- a/Source/WebCore/rendering/RenderObject.h
+++ b/Source/WebCore/rendering/RenderObject.h
@@ -58,6 +58,7 @@ class RenderInline;
class RenderBlock;
class RenderFlowThread;
class RenderLayer;
+class RenderTable;
class RenderTheme;
class TransformState;
class VisiblePosition;
@@ -219,6 +220,8 @@ public:
// normal flow object.
void handleDynamicFloatPositionChange();
+ RenderTable* createAnonymousTable() const;
+
// RenderObject tree manipulation
//////////////////////////////////////////
virtual bool canHaveChildren() const { return virtualChildren(); }
@@ -352,6 +355,8 @@ public:
bool isHTMLMarquee() const;
+ bool isTablePart() const { return isTableCell() || isTableCol() || isTableCaption() || isTableRow() || isTableSection(); }
+
inline bool isBeforeContent() const;
inline bool isAfterContent() const;
inline bool isBeforeOrAfterContent() const;
@@ -359,16 +364,6 @@ public:
static inline bool isAfterContent(const RenderObject* obj) { return obj && obj->isAfterContent(); }
static inline bool isBeforeOrAfterContent(const RenderObject* obj) { return obj && obj->isBeforeOrAfterContent(); }
- inline RenderObject* anonymousContainer(RenderObject* child)
- {
- RenderObject* container = child;
- while (container->parent() != this)
- container = container->parent();
-
- ASSERT(container->isAnonymous());
- return container;
- }
-
bool hasCounterNodeMap() const { return m_bitfields.hasCounterNodeMap(); }
void setHasCounterNodeMap(bool hasCounterNodeMap) { m_bitfields.setHasCounterNodeMap(hasCounterNodeMap); }
bool everHadLayout() const { return m_bitfields.everHadLayout(); }
@@ -392,7 +387,8 @@ public:
// to add SVG renderer methods to RenderObject with an ASSERT_NOT_REACHED() default implementation.
virtual bool isSVGRoot() const { return false; }
virtual bool isSVGContainer() const { return false; }
- virtual bool isSVGViewportContainer() const { return false; }
+ virtual bool isSVGTransformableContainer() const { return false; }
+ virtual bool isSVGViewportContainer() const { return false; }
virtual bool isSVGGradientStop() const { return false; }
virtual bool isSVGHiddenContainer() const { return false; }
virtual bool isSVGPath() const { return false; }
@@ -801,6 +797,7 @@ public:
// as a hook to detect the case of document destruction and don't waste time doing unnecessary work.
bool documentBeingDestroyed() const;
+ void destroyAndCleanupAnonymousWrappers();
virtual void destroy();
// Virtual function helpers for the deprecated Flexible Box Layout (display: -webkit-box).
@@ -856,13 +853,15 @@ public:
RenderObject* rendererForRootBackground();
protected:
+ inline bool layerCreationAllowedForSubtree() const;
+
// Overrides should call the superclass at the end
virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
// Overrides should call the superclass at the start
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
void propagateStyleToAnonymousChildren(bool blockChildrenOnly = false);
- void drawLineForBoxSide(GraphicsContext*, LayoutUnit x1, LayoutUnit y1, LayoutUnit x2, LayoutUnit y2, BoxSide,
+ void drawLineForBoxSide(GraphicsContext*, int x1, int y1, int x2, int y2, BoxSide,
Color, EBorderStyle, int adjbw1, int adjbw2, bool antialias = false);
void paintFocusRing(GraphicsContext*, const LayoutPoint&, RenderStyle*);
@@ -1107,6 +1106,20 @@ inline bool RenderObject::preservesNewline() const
return style()->preserveNewline();
}
+inline bool RenderObject::layerCreationAllowedForSubtree() const
+{
+#if ENABLE(SVG)
+ RenderObject* parentRenderer = parent();
+ while (parentRenderer) {
+ if (parentRenderer->isSVGHiddenContainer())
+ return false;
+ parentRenderer = parentRenderer->parent();
+ }
+#endif
+
+ return true;
+}
+
inline void makeMatrixRenderable(TransformationMatrix& matrix, bool has3DRendering)
{
#if !ENABLE(3D_RENDERING)
diff --git a/Source/WebCore/rendering/RenderObjectChildList.cpp b/Source/WebCore/rendering/RenderObjectChildList.cpp
index 24055bb16..efe6b8520 100644
--- a/Source/WebCore/rendering/RenderObjectChildList.cpp
+++ b/Source/WebCore/rendering/RenderObjectChildList.cpp
@@ -520,7 +520,15 @@ void RenderObjectChildList::updateBeforeAfterContent(RenderObject* owner, Pseudo
renderer->destroy();
return;
}
- owner->addChild(generatedContentContainer, insertBefore);
+
+ // When we don't have a first child and are part of a continuation chain,
+ // insertBefore is incorrectly set to zero above, which causes the :before
+ // child to end up at the end of continuation chain.
+ // See https://bugs.webkit.org/show_bug.cgi?id=78380.
+ if (!insertBefore && type == BEFORE && owner->virtualContinuation())
+ owner->addChildIgnoringContinuation(generatedContentContainer, 0);
+ else
+ owner->addChild(generatedContentContainer, insertBefore);
}
if (generatedContentContainer->isChildAllowed(renderer, pseudoElementStyle))
generatedContentContainer->addChild(renderer);
diff --git a/Source/WebCore/rendering/RenderProgress.h b/Source/WebCore/rendering/RenderProgress.h
index 62436fdc0..fa92bb20b 100644
--- a/Source/WebCore/rendering/RenderProgress.h
+++ b/Source/WebCore/rendering/RenderProgress.h
@@ -45,7 +45,6 @@ private:
virtual const char* renderName() const { return "RenderProgress"; }
virtual bool isProgress() const { return true; }
virtual bool requiresForcedStyleRecalcPropagation() const { return true; }
- virtual bool canHaveChildren() const { return false; }
virtual void updateFromElement();
void animationTimerFired(Timer<RenderProgress>*);
diff --git a/Source/WebCore/rendering/RenderRegion.cpp b/Source/WebCore/rendering/RenderRegion.cpp
index 8df1ced4c..42f7d2955 100644
--- a/Source/WebCore/rendering/RenderRegion.cpp
+++ b/Source/WebCore/rendering/RenderRegion.cpp
@@ -47,7 +47,9 @@ RenderRegion::RenderRegion(Node* node, RenderFlowThread* flowThread)
, m_parentFlowThread(0)
, m_isValid(false)
, m_hasCustomRegionStyle(false)
+ , m_regionState(RegionUndefined)
{
+ ASSERT(node->document()->cssRegionsEnabled());
}
LayoutRect RenderRegion::regionOverflowRect() const
@@ -157,7 +159,8 @@ bool RenderRegion::nodeAtPoint(const HitTestRequest& request, HitTestResult& res
// Check our bounds next. For this purpose always assume that we can only be hit in the
// foreground phase (which is true for replaced elements like images).
- LayoutRect boundsRect(adjustedLocation, size());
+ LayoutRect boundsRect = borderBoxRectInRegion(result.region());
+ boundsRect.moveBy(adjustedLocation);
if (visibleToHitTesting() && action == HitTestForeground && boundsRect.intersects(result.rectForPoint(pointInContainer))) {
// Check the contents of the RenderFlowThread.
if (m_flowThread && m_flowThread->hitTestRegion(this, request, result, pointInContainer, LayoutPoint(adjustedLocation.x() + borderLeft() + paddingLeft(), adjustedLocation.y() + borderTop() + paddingTop())))
diff --git a/Source/WebCore/rendering/RenderRegion.h b/Source/WebCore/rendering/RenderRegion.h
index 6bdcdf672..d46d6da67 100644
--- a/Source/WebCore/rendering/RenderRegion.h
+++ b/Source/WebCore/rendering/RenderRegion.h
@@ -81,6 +81,16 @@ public:
bool isLastRegion() const;
void clearBoxStyleInRegion(const RenderBox*);
+
+ enum RegionState {
+ RegionUndefined,
+ RegionEmpty,
+ RegionFit,
+ RegionOverflow
+ };
+
+ RegionState regionState() const { return isValid() ? m_regionState : RegionUndefined; }
+ void setRegionState(RegionState regionState) { m_regionState = regionState; }
private:
virtual const char* renderName() const { return "RenderRegion"; }
@@ -109,6 +119,7 @@ private:
bool m_isValid;
bool m_hasCustomRegionStyle;
+ RegionState m_regionState;
};
inline RenderRegion* toRenderRegion(RenderObject* object)
diff --git a/Source/WebCore/rendering/RenderReplaced.cpp b/Source/WebCore/rendering/RenderReplaced.cpp
index 82c344866..6bdb1831c 100644
--- a/Source/WebCore/rendering/RenderReplaced.cpp
+++ b/Source/WebCore/rendering/RenderReplaced.cpp
@@ -438,7 +438,7 @@ void RenderReplaced::computePreferredLogicalWidths()
m_maxPreferredLogicalWidth = computeReplacedLogicalWidth(false) + borderAndPadding;
if (style()->maxWidth().isFixed())
- m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, style()->maxWidth().value() + (style()->boxSizing() == CONTENT_BOX ? borderAndPadding : 0));
+ m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, style()->maxWidth().value() + (style()->boxSizing() == CONTENT_BOX ? borderAndPadding : zeroLayoutUnit));
if (style()->width().isPercent() || style()->height().isPercent()
|| style()->maxWidth().isPercent() || style()->maxHeight().isPercent()
diff --git a/Source/WebCore/rendering/RenderTable.cpp b/Source/WebCore/rendering/RenderTable.cpp
index 5de2ddbda..1a42652db 100644
--- a/Source/WebCore/rendering/RenderTable.cpp
+++ b/Source/WebCore/rendering/RenderTable.cpp
@@ -232,14 +232,16 @@ void RenderTable::computeLogicalWidth()
setLogicalWidth(convertStyleLogicalWidthToComputedWidth(styleLogicalWidth, containerWidthInInlineDirection));
else {
// Subtract out any fixed margins from our available width for auto width tables.
- LayoutUnit marginTotal = 0;
- if (!style()->marginStart().isAuto())
- marginTotal += style()->marginStart().calcValue(availableLogicalWidth);
- if (!style()->marginEnd().isAuto())
- marginTotal += style()->marginEnd().calcValue(availableLogicalWidth);
-
+ LayoutUnit marginStart = style()->marginStart().calcMinValue(availableLogicalWidth);
+ LayoutUnit marginEnd = style()->marginEnd().calcMinValue(availableLogicalWidth);
+ LayoutUnit marginTotal = marginStart + marginEnd;
+
// Subtract out our margins to get the available content width.
LayoutUnit availableContentLogicalWidth = max<LayoutUnit>(0, containerWidthInInlineDirection - marginTotal);
+ if (shrinkToAvoidFloats() && cb->containsFloats() && !hasPerpendicularContainingBlock) {
+ // FIXME: Work with regions someday.
+ availableContentLogicalWidth = shrinkLogicalWidthToAvoidFloats(marginStart, marginEnd, cb, 0, 0);
+ }
// Ensure we aren't bigger than our available width.
setLogicalWidth(min(availableContentLogicalWidth, maxPreferredLogicalWidth()));
@@ -272,7 +274,7 @@ LayoutUnit RenderTable::convertStyleLogicalWidthToComputedWidth(const Length& st
bool isCSSTable = !node() || !node()->hasTagName(tableTag);
if (isCSSTable && styleLogicalWidth.isFixed() && styleLogicalWidth.isPositive()) {
recalcBordersInRowDirection();
- borders = borderStart() + borderEnd() + (collapseBorders() ? 0 : paddingStart() + paddingEnd());
+ borders = borderStart() + borderEnd() + (collapseBorders() ? zeroLayoutUnit : paddingStart() + paddingEnd());
}
return styleLogicalWidth.calcMinValue(availableWidth) + borders;
}
@@ -370,8 +372,8 @@ void RenderTable::layout()
}
}
- LayoutUnit borderAndPaddingBefore = borderBefore() + (collapsing ? 0 : paddingBefore());
- LayoutUnit borderAndPaddingAfter = borderAfter() + (collapsing ? 0 : paddingAfter());
+ LayoutUnit borderAndPaddingBefore = borderBefore() + (collapsing ? zeroLayoutUnit : paddingBefore());
+ LayoutUnit borderAndPaddingAfter = borderAfter() + (collapsing ? zeroLayoutUnit : paddingAfter());
setLogicalHeight(logicalHeight() + borderAndPaddingBefore);
@@ -382,7 +384,7 @@ void RenderTable::layout()
LayoutUnit computedLogicalHeight = 0;
if (logicalHeightLength.isFixed()) {
// HTML tables size as though CSS height includes border/padding, CSS tables do not.
- LayoutUnit borders = node() && node()->hasTagName(tableTag) ? (borderAndPaddingBefore + borderAndPaddingAfter) : 0;
+ LayoutUnit borders = node() && node()->hasTagName(tableTag) ? (borderAndPaddingBefore + borderAndPaddingAfter) : zeroLayoutUnit;
computedLogicalHeight = logicalHeightLength.value() - borders;
} else if (logicalHeightLength.isPercent())
computedLogicalHeight = computePercentageLogicalHeight(logicalHeightLength);
@@ -390,11 +392,11 @@ void RenderTable::layout()
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
if (child->isTableSection())
- // FIXME: Distribute extra height between all table body sections instead of giving it all to the first one.
- toRenderTableSection(child)->layoutRows(child == m_firstBody ? max<LayoutUnit>(0, computedLogicalHeight - totalSectionLogicalHeight) : 0);
+ // FIXME: Distribute the extra logical height between all table sections instead of giving it all to the first one.
+ toRenderTableSection(child)->layoutRows(child == topSection() ? max<LayoutUnit>(0, computedLogicalHeight - totalSectionLogicalHeight) : 0);
}
- if (!m_firstBody && computedLogicalHeight > totalSectionLogicalHeight && !document()->inQuirksMode()) {
+ if (!topSection() && computedLogicalHeight > totalSectionLogicalHeight && !document()->inQuirksMode()) {
// Completely empty tables (with no sections or anything) should at least honor specified height
// in strict mode.
setLogicalHeight(logicalHeight() + computedLogicalHeight);
@@ -617,7 +619,8 @@ void RenderTable::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint& p
LayoutRect rect(paintOffset, size());
subtractCaptionRect(rect);
- paintBoxShadow(paintInfo, rect, style(), Normal);
+ if (!boxShadowShouldBeAppliedToBackground(determineBackgroundBleedAvoidance(paintInfo.context)))
+ paintBoxShadow(paintInfo, rect, style(), Normal);
paintBackground(paintInfo, rect);
paintBoxShadow(paintInfo, rect, style(), Inset);
diff --git a/Source/WebCore/rendering/RenderTable.h b/Source/WebCore/rendering/RenderTable.h
index ba9fd3983..9a6557e03 100644
--- a/Source/WebCore/rendering/RenderTable.h
+++ b/Source/WebCore/rendering/RenderTable.h
@@ -172,7 +172,7 @@ public:
LayoutUnit bordersPaddingAndSpacingInRowDirection() const
{
return borderStart() + borderEnd() +
- (collapseBorders() ? 0 : (paddingStart() + paddingEnd() + (numEffCols() + 1) * hBorderSpacing()));
+ (collapseBorders() ? zeroLayoutUnit : (paddingStart() + paddingEnd() + (numEffCols() + 1) * hBorderSpacing()));
}
RenderTableCol* colElement(unsigned col, bool* startEdge = 0, bool* endEdge = 0) const;
diff --git a/Source/WebCore/rendering/RenderTableCell.cpp b/Source/WebCore/rendering/RenderTableCell.cpp
index 5b690f4c7..434ac0d69 100644
--- a/Source/WebCore/rendering/RenderTableCell.cpp
+++ b/Source/WebCore/rendering/RenderTableCell.cpp
@@ -91,6 +91,25 @@ void RenderTableCell::colSpanOrRowSpanChanged()
section()->setNeedsCellRecalc();
}
+LayoutUnit RenderTableCell::logicalHeightForRowSizing() const
+{
+ LayoutUnit adjustedLogicalHeight = logicalHeight() - (intrinsicPaddingBefore() + intrinsicPaddingAfter());
+
+ LayoutUnit styleLogicalHeight = style()->logicalHeight().calcValue(0);
+ if (document()->inQuirksMode() || style()->boxSizing() == BORDER_BOX) {
+ // Explicit heights use the border box in quirks mode.
+ // Don't adjust height.
+ } else {
+ // In strict mode, box-sizing: content-box do the right
+ // thing and actually add in the border and padding.
+ LayoutUnit adjustedPaddingBefore = paddingBefore() - intrinsicPaddingBefore();
+ LayoutUnit adjustedPaddingAfter = paddingAfter() - intrinsicPaddingAfter();
+ styleLogicalHeight += adjustedPaddingBefore + adjustedPaddingAfter + borderBefore() + borderAfter();
+ }
+
+ return max(styleLogicalHeight, adjustedLogicalHeight);
+}
+
Length RenderTableCell::styleOrColLogicalWidth() const
{
Length w = style()->logicalWidth();
@@ -1068,6 +1087,11 @@ void RenderTableCell::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOf
paintMaskImages(paintInfo, LayoutRect(paintOffset, size()));
}
+bool RenderTableCell::boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance, InlineFlowBox*) const
+{
+ return false;
+}
+
void RenderTableCell::scrollbarsChanged(bool horizontalScrollbarChanged, bool verticalScrollbarChanged)
{
LayoutUnit scrollbarHeight = scrollbarLogicalHeight();
diff --git a/Source/WebCore/rendering/RenderTableCell.h b/Source/WebCore/rendering/RenderTableCell.h
index 2548b4713..e0b4a0558 100644
--- a/Source/WebCore/rendering/RenderTableCell.h
+++ b/Source/WebCore/rendering/RenderTableCell.h
@@ -85,6 +85,8 @@ public:
Length styleOrColLogicalWidth() const;
+ LayoutUnit logicalHeightForRowSizing() const;
+
virtual void computePreferredLogicalWidths();
void updateLogicalWidth(LayoutUnit);
@@ -151,6 +153,8 @@ private:
virtual void paintBoxDecorations(PaintInfo&, const LayoutPoint&);
virtual void paintMask(PaintInfo&, const LayoutPoint&);
+ virtual bool boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance, InlineFlowBox*) const OVERRIDE;
+
virtual LayoutSize offsetFromContainer(RenderObject*, const LayoutPoint&) const;
virtual LayoutRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const;
virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, LayoutRect&, bool fixed = false) const;
diff --git a/Source/WebCore/rendering/RenderTableSection.cpp b/Source/WebCore/rendering/RenderTableSection.cpp
index fd55a6321..844209c8d 100644
--- a/Source/WebCore/rendering/RenderTableSection.cpp
+++ b/Source/WebCore/rendering/RenderTableSection.cpp
@@ -334,14 +334,10 @@ int RenderTableSection::calcRowLogicalHeight()
m_rowPos[0] = spacing;
for (unsigned r = 0; r < m_grid.size(); r++) {
- m_rowPos[r + 1] = 0;
- m_grid[r].baseline = 0;
- LayoutUnit baseline = 0;
- int bdesc = 0;
- int ch = m_grid[r].logicalHeight.calcMinValue(0);
- int pos = m_rowPos[r] + ch + (m_grid[r].rowRenderer ? spacing : 0);
+ LayoutUnit baselineDescent = 0;
- m_rowPos[r + 1] = max(m_rowPos[r + 1], pos);
+ // Our base size is the biggest logical height from our cells' styles (excluding row spanning cells).
+ m_rowPos[r + 1] = max(m_rowPos[r] + m_grid[r].logicalHeight.calcMinValue(0), 0);
Row& row = m_grid[r].row;
unsigned totalCols = row.size();
@@ -353,10 +349,13 @@ int RenderTableSection::calcRowLogicalHeight()
if (!cell || current.inColSpan)
continue;
- if ((cell->row() + cell->rowSpan() - 1) > r)
+ // FIXME: We are always adding the height of a rowspan to the last rows which doesn't match
+ // other browsers. See webkit.org/b/52185 for example.
+ if ((cell->row() + cell->rowSpan() - 1) != r)
continue;
- unsigned indx = max(r - cell->rowSpan() + 1, 0u);
+ // For row spanning cells, |r| is the last row in the span.
+ unsigned cellStartRow = cell->row();
if (cell->hasOverrideHeight()) {
if (!statePusher.didPush()) {
@@ -370,43 +369,27 @@ int RenderTableSection::calcRowLogicalHeight()
cell->layoutIfNeeded();
}
- int adjustedLogicalHeight = cell->logicalHeight() - (cell->intrinsicPaddingBefore() + cell->intrinsicPaddingAfter());
-
- ch = cell->style()->logicalHeight().calcValue(0);
- if (document()->inQuirksMode() || cell->style()->boxSizing() == BORDER_BOX) {
- // Explicit heights use the border box in quirks mode.
- // Don't adjust height.
- } else {
- // In strict mode, box-sizing: content-box do the right
- // thing and actually add in the border and padding.
- int adjustedPaddingBefore = cell->paddingBefore() - cell->intrinsicPaddingBefore();
- int adjustedPaddingAfter = cell->paddingAfter() - cell->intrinsicPaddingAfter();
- ch += adjustedPaddingBefore + adjustedPaddingAfter + cell->borderBefore() + cell->borderAfter();
- }
- ch = max(ch, adjustedLogicalHeight);
-
- pos = m_rowPos[indx] + ch + (m_grid[r].rowRenderer ? spacing : 0);
-
- m_rowPos[r + 1] = max(m_rowPos[r + 1], pos);
+ int cellLogicalHeight = cell->logicalHeightForRowSizing();
+ m_rowPos[r + 1] = max(m_rowPos[r + 1], m_rowPos[cellStartRow] + cellLogicalHeight);
// find out the baseline
EVerticalAlign va = cell->style()->verticalAlign();
if (va == BASELINE || va == TEXT_BOTTOM || va == TEXT_TOP || va == SUPER || va == SUB) {
- int b = cell->cellBaselinePosition();
- if (b > cell->borderBefore() + cell->paddingBefore()) {
- baseline = max<LayoutUnit>(baseline, b - cell->intrinsicPaddingBefore());
- bdesc = max(bdesc, m_rowPos[indx] + ch - (b - cell->intrinsicPaddingBefore()));
+ int baselinePosition = cell->cellBaselinePosition();
+ if (baselinePosition > cell->borderBefore() + cell->paddingBefore()) {
+ m_grid[r].baseline = max(m_grid[r].baseline, baselinePosition - cell->intrinsicPaddingBefore());
+ baselineDescent = max(baselineDescent, m_rowPos[cellStartRow] + cellLogicalHeight - (baselinePosition - cell->intrinsicPaddingBefore()));
}
}
}
// do we have baseline aligned elements?
- if (baseline) {
+ if (m_grid[r].baseline)
// increase rowheight if baseline requires
- m_rowPos[r + 1] = max(m_rowPos[r + 1], baseline + bdesc + (m_grid[r].rowRenderer ? spacing : 0));
- m_grid[r].baseline = baseline;
- }
+ m_rowPos[r + 1] = max(m_rowPos[r + 1], m_grid[r].baseline + baselineDescent);
+ // Add the border-spacing to our final position.
+ m_rowPos[r + 1] += m_grid[r].rowRenderer ? spacing : 0;
m_rowPos[r + 1] = max(m_rowPos[r + 1], m_rowPos[r]);
}
@@ -1306,6 +1289,9 @@ bool RenderTableSection::nodeAtPoint(const HitTestRequest& request, HitTestResul
}
LayoutUnit offsetInColumnDirection = style()->isHorizontalWritingMode() ? location.y() : location.x();
+
+ recalcCellsIfNeeded();
+
// Find the first row that starts after offsetInColumnDirection.
unsigned nextRow = std::upper_bound(m_rowPos.begin(), m_rowPos.end(), offsetInColumnDirection) - m_rowPos.begin();
if (nextRow == m_rowPos.size())
diff --git a/Source/WebCore/rendering/RenderText.cpp b/Source/WebCore/rendering/RenderText.cpp
index f6c0373eb..f2408dbcc 100644
--- a/Source/WebCore/rendering/RenderText.cpp
+++ b/Source/WebCore/rendering/RenderText.cpp
@@ -300,7 +300,7 @@ void RenderText::deleteTextBoxes()
PassRefPtr<StringImpl> RenderText::originalText() const
{
Node* e = node();
- return (e && e->isTextNode()) ? static_cast<Text*>(e)->dataImpl() : 0;
+ return (e && e->isTextNode()) ? toText(e)->dataImpl() : 0;
}
void RenderText::absoluteRects(Vector<LayoutRect>& rects, const LayoutPoint& accumulatedOffset) const
diff --git a/Source/WebCore/rendering/RenderTextControl.h b/Source/WebCore/rendering/RenderTextControl.h
index 744878af4..aa936e7a0 100644
--- a/Source/WebCore/rendering/RenderTextControl.h
+++ b/Source/WebCore/rendering/RenderTextControl.h
@@ -70,7 +70,6 @@ private:
virtual bool isTextControl() const { return true; }
virtual void computePreferredLogicalWidths();
virtual void removeLeftoverAnonymousBlock(RenderBlock*) { }
- virtual bool canHaveChildren() const { return false; }
virtual bool avoidsFloats() const { return true; }
virtual void addFocusRingRects(Vector<LayoutRect>&, const LayoutPoint&);
diff --git a/Source/WebCore/rendering/RenderTextControlSingleLine.cpp b/Source/WebCore/rendering/RenderTextControlSingleLine.cpp
index a86850ce4..a44e2886c 100644
--- a/Source/WebCore/rendering/RenderTextControlSingleLine.cpp
+++ b/Source/WebCore/rendering/RenderTextControlSingleLine.cpp
@@ -60,7 +60,7 @@ VisiblePosition RenderTextControlInnerBlock::positionForPoint(const LayoutPoint&
if (m_multiLine) {
RenderTextControl* renderer = toRenderTextControl(node()->shadowAncestorNode()->renderer());
if (renderer->hasOverflowClip())
- contentsPoint += renderer->layer()->scrolledContentOffset();
+ contentsPoint += renderer->scrolledContentOffset();
}
return RenderBlock::positionForPoint(contentsPoint);
@@ -175,7 +175,7 @@ void RenderTextControlSingleLine::showPopup()
m_searchPopup->saveRecentSearches(name, m_recentSearches);
}
- m_searchPopup->popupMenu()->show(absoluteBoundingBoxRect(), document()->view(), -1);
+ m_searchPopup->popupMenu()->show(pixelSnappedIntRect(absoluteBoundingBoxRect()), document()->view(), -1);
}
void RenderTextControlSingleLine::hidePopup()
@@ -196,7 +196,7 @@ void RenderTextControlSingleLine::paint(PaintInfo& paintInfo, const LayoutPoint&
// Convert the rect into the coords used for painting the content
contentsRect.moveBy(paintOffset + location());
- theme()->paintCapsLockIndicator(this, paintInfo, contentsRect);
+ theme()->paintCapsLockIndicator(this, paintInfo, pixelSnappedIntRect(contentsRect));
}
}
@@ -332,7 +332,7 @@ void RenderTextControlSingleLine::styleDidChange(StyleDifference diff, const Ren
containerRenderer->style()->setWidth(Length());
}
if (HTMLElement* placeholder = inputElement()->placeholderElement())
- placeholder->ensureInlineStyleDecl()->setProperty(CSSPropertyTextOverflow, textShouldBeTruncated() ? CSSValueEllipsis : CSSValueClip);
+ placeholder->setInlineStyleProperty(CSSPropertyTextOverflow, textShouldBeTruncated() ? CSSValueEllipsis : CSSValueClip);
setHasOverflowClip(false);
}
diff --git a/Source/WebCore/rendering/RenderTextFragment.cpp b/Source/WebCore/rendering/RenderTextFragment.cpp
index 17c9d7b77..ff4082422 100644
--- a/Source/WebCore/rendering/RenderTextFragment.cpp
+++ b/Source/WebCore/rendering/RenderTextFragment.cpp
@@ -52,7 +52,7 @@ RenderTextFragment::~RenderTextFragment()
PassRefPtr<StringImpl> RenderTextFragment::originalText() const
{
Node* e = node();
- RefPtr<StringImpl> result = ((e && e->isTextNode()) ? static_cast<Text*>(e)->dataImpl() : contentString());
+ RefPtr<StringImpl> result = ((e && e->isTextNode()) ? toText(e)->dataImpl() : contentString());
if (!result)
return 0;
return result->substring(start(), end());
@@ -95,7 +95,7 @@ UChar RenderTextFragment::previousCharacter() const
{
if (start()) {
Node* e = node();
- StringImpl* original = ((e && e->isTextNode()) ? static_cast<Text*>(e)->dataImpl() : contentString());
+ StringImpl* original = ((e && e->isTextNode()) ? toText(e)->dataImpl() : contentString());
if (original && start() <= original->length())
return (*original)[start() - 1];
}
diff --git a/Source/WebCore/rendering/RenderTheme.cpp b/Source/WebCore/rendering/RenderTheme.cpp
index d93a27e25..6be2f5efb 100644
--- a/Source/WebCore/rendering/RenderTheme.cpp
+++ b/Source/WebCore/rendering/RenderTheme.cpp
@@ -1,7 +1,7 @@
/**
* This file is part of the theme implementation for form controls in WebCore.
*
- * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Computer, Inc.
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -1125,18 +1125,21 @@ Color RenderTheme::focusRingColor()
return customFocusRingColor().isValid() ? customFocusRingColor() : defaultTheme()->platformFocusRingColor();
}
-String RenderTheme::fileListNameForWidth(const Vector<String>& filenames, const Font& font, int width, bool multipleFilesAllowed)
+String RenderTheme::fileListDefaultLabel(bool multipleFilesAllowed) const
+{
+ if (multipleFilesAllowed)
+ return fileButtonNoFilesSelectedLabel();
+ return fileButtonNoFileSelectedLabel();
+}
+
+String RenderTheme::fileListNameForWidth(const Vector<String>& filenames, const Font& font, int width, bool multipleFilesAllowed) const
{
if (width <= 0)
return String();
String string;
- if (filenames.isEmpty()) {
- if (multipleFilesAllowed)
- string = fileButtonNoFilesSelectedLabel();
- else
- string = fileButtonNoFileSelectedLabel();
- }
+ if (filenames.isEmpty())
+ string = fileListDefaultLabel(multipleFilesAllowed);
else if (filenames.size() == 1)
string = pathGetFileName(filenames[0]);
else
diff --git a/Source/WebCore/rendering/RenderTheme.h b/Source/WebCore/rendering/RenderTheme.h
index c243b78a5..f65b8523f 100644
--- a/Source/WebCore/rendering/RenderTheme.h
+++ b/Source/WebCore/rendering/RenderTheme.h
@@ -1,7 +1,7 @@
/*
* This file is part of the theme implementation for form controls in WebCore.
*
- * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Computer, Inc.
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -214,7 +214,8 @@ public:
virtual bool popsMenuByArrowKeys() const { return false; }
virtual bool popsMenuBySpaceOrReturn() const { return false; }
- virtual String fileListNameForWidth(const Vector<String>& filenames, const Font&, int width, bool multipleFilesAllowed);
+ virtual String fileListDefaultLabel(bool multipleFilesAllowed) const;
+ virtual String fileListNameForWidth(const Vector<String>& filenames, const Font&, int width, bool multipleFilesAllowed) const;
protected:
// The platform selection color.
diff --git a/Source/WebCore/rendering/RenderThemeChromiumAndroid.cpp b/Source/WebCore/rendering/RenderThemeChromiumAndroid.cpp
index c45fc2086..88ac3a8d6 100644
--- a/Source/WebCore/rendering/RenderThemeChromiumAndroid.cpp
+++ b/Source/WebCore/rendering/RenderThemeChromiumAndroid.cpp
@@ -63,6 +63,12 @@ Color RenderThemeChromiumAndroid::systemColor(int cssValueId) const
return RenderTheme::systemColor(cssValueId);
}
+String RenderThemeChromiumAndroid::extraDefaultStyleSheet()
+{
+ return RenderThemeChromiumLinux::extraDefaultStyleSheet() +
+ String(themeChromiumAndroidUserAgentStyleSheet, sizeof(themeChromiumAndroidUserAgentStyleSheet));
+}
+
void RenderThemeChromiumAndroid::adjustInnerSpinButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
{
if (PlatformSupport::layoutTestMode()) {
diff --git a/Source/WebCore/rendering/RenderThemeChromiumAndroid.h b/Source/WebCore/rendering/RenderThemeChromiumAndroid.h
index e7b9d9885..5fb12bc02 100644
--- a/Source/WebCore/rendering/RenderThemeChromiumAndroid.h
+++ b/Source/WebCore/rendering/RenderThemeChromiumAndroid.h
@@ -33,14 +33,25 @@ namespace WebCore {
class RenderThemeChromiumAndroid : public RenderThemeChromiumLinux {
public:
static PassRefPtr<RenderTheme> create();
+ virtual String extraDefaultStyleSheet() OVERRIDE;
- virtual Color systemColor(int cssValidId) const;
+ virtual Color systemColor(int cssValidId) const OVERRIDE;
- virtual void adjustInnerSpinButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
+ virtual void adjustInnerSpinButtonStyle(CSSStyleSelector*, RenderStyle*, Element*) const OVERRIDE;
+
+ virtual bool delegatesMenuListRendering() const OVERRIDE { return true; }
+
+#if ENABLE(TOUCH_EVENTS)
+ virtual Color platformTapHighlightColor() const OVERRIDE
+ {
+ return RenderThemeChromiumAndroid::defaultTapHighlightColor;
+ }
+#endif
private:
virtual ~RenderThemeChromiumAndroid();
+ static const RGBA32 defaultTapHighlightColor = 0x6633b5e5;
};
} // namespace WebCore
diff --git a/Source/WebCore/rendering/RenderThemeMac.h b/Source/WebCore/rendering/RenderThemeMac.h
index dc1af04d0..25065c422 100644
--- a/Source/WebCore/rendering/RenderThemeMac.h
+++ b/Source/WebCore/rendering/RenderThemeMac.h
@@ -1,7 +1,7 @@
/*
* This file is part of the theme implementation for form controls in WebCore.
*
- * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Computer, Inc.
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -175,7 +175,7 @@ protected:
virtual bool shouldShowPlaceholderWhenFocused() const;
private:
- virtual String fileListNameForWidth(const Vector<String>& filenames, const Font&, int width, bool multipleFilesAllowed);
+ virtual String fileListNameForWidth(const Vector<String>& filenames, const Font&, int width, bool multipleFilesAllowed) const;
LayoutRect inflateRect(const LayoutRect&, const IntSize&, const int* margins, float zoomLevel = 1.0f) const;
diff --git a/Source/WebCore/rendering/RenderThemeMac.mm b/Source/WebCore/rendering/RenderThemeMac.mm
index e405f6ceb..cd566e859 100644
--- a/Source/WebCore/rendering/RenderThemeMac.mm
+++ b/Source/WebCore/rendering/RenderThemeMac.mm
@@ -2115,18 +2115,14 @@ NSTextFieldCell* RenderThemeMac::textField() const
return m_textField.get();
}
-String RenderThemeMac::fileListNameForWidth(const Vector<String>& filenames, const Font& font, int width, bool multipleFilesAllowed)
+String RenderThemeMac::fileListNameForWidth(const Vector<String>& filenames, const Font& font, int width, bool multipleFilesAllowed) const
{
if (width <= 0)
return String();
String strToTruncate;
- if (filenames.isEmpty()) {
- if (multipleFilesAllowed)
- strToTruncate = fileButtonNoFilesSelectedLabel();
- else
- strToTruncate = fileButtonNoFileSelectedLabel();
- }
+ if (filenames.isEmpty())
+ strToTruncate = fileListDefaultLabel(multipleFilesAllowed);
else if (filenames.size() == 1)
strToTruncate = [[NSFileManager defaultManager] displayNameAtPath:(filenames[0])];
else
diff --git a/Source/WebCore/rendering/RenderTreeAsText.cpp b/Source/WebCore/rendering/RenderTreeAsText.cpp
index 06e0fe98e..4cb4c0e67 100644
--- a/Source/WebCore/rendering/RenderTreeAsText.cpp
+++ b/Source/WebCore/rendering/RenderTreeAsText.cpp
@@ -69,7 +69,7 @@
#endif
#if PLATFORM(QT)
-#include <QWidget>
+#include <QVariant>
#endif
namespace WebCore {
@@ -475,14 +475,13 @@ void RenderTreeAsText::writeRenderObject(TextStream& ts, const RenderObject& o,
if (o.isRenderPart()) {
const RenderPart* part = toRenderPart(const_cast<RenderObject*>(&o));
if (part->widget() && part->widget()->platformWidget()) {
- QWidget* wid = part->widget()->platformWidget();
+ QObject* wid = part->widget()->platformWidget();
ts << " [QT: ";
- ts << "geometry: {" << wid->geometry() << "} ";
- ts << "isHidden: " << wid->isHidden() << " ";
+ ts << "geometry: {" << wid->property("geometry").toRect() << "} ";
+ ts << "isHidden: " << !wid->property("isVisible").toBool() << " ";
ts << "isSelfVisible: " << part->widget()->isSelfVisible() << " ";
- ts << "isParentVisible: " << part->widget()->isParentVisible() << " ";
- ts << "mask: {" << wid->mask().boundingRect() << "} ] ";
+ ts << "isParentVisible: " << part->widget()->isParentVisible() << " ] ";
}
}
#endif
diff --git a/Source/WebCore/rendering/RenderWidget.cpp b/Source/WebCore/rendering/RenderWidget.cpp
index 2c9565134..ad5a03fd2 100644
--- a/Source/WebCore/rendering/RenderWidget.cpp
+++ b/Source/WebCore/rendering/RenderWidget.cpp
@@ -308,7 +308,7 @@ void RenderWidget::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
// Paint a partially transparent wash over selected widgets.
if (isSelected() && !document()->printing()) {
// FIXME: selectionRect() is in absolute, not painting coordinates.
- paintInfo.context->fillRect(selectionRect(), selectionBackgroundColor(), style()->colorSpace());
+ paintInfo.context->fillRect(pixelSnappedIntRect(selectionRect()), selectionBackgroundColor(), style()->colorSpace());
}
}
diff --git a/Source/WebCore/rendering/RootInlineBox.cpp b/Source/WebCore/rendering/RootInlineBox.cpp
index 2acfaf02c..8d84bfe61 100644
--- a/Source/WebCore/rendering/RootInlineBox.cpp
+++ b/Source/WebCore/rendering/RootInlineBox.cpp
@@ -286,7 +286,7 @@ LayoutUnit RootInlineBox::alignBoxesInBlockDirection(LayoutUnit heightOfBlock, G
heightOfBlock += annotationsAdjustment;
}
- LayoutUnit gridSnapAdjustment = lineGridSnapAdjustment();
+ LayoutUnit gridSnapAdjustment = lineSnapAdjustment();
if (gridSnapAdjustment) {
adjustBlockDirectionPosition(gridSnapAdjustment);
heightOfBlock += gridSnapAdjustment;
@@ -326,11 +326,11 @@ int RootInlineBox::beforeAnnotationsAdjustment() const
return result;
}
-LayoutUnit RootInlineBox::lineGridSnapAdjustment(LayoutUnit delta) const
+LayoutUnit RootInlineBox::lineSnapAdjustment(LayoutUnit delta) const
{
// If our block doesn't have snapping turned on, do nothing.
// FIXME: Implement bounds snapping.
- if (block()->style()->lineGridSnap() == LineGridSnapNone)
+ if (block()->style()->lineSnap() == LineSnapNone)
return 0;
// Get the current line grid and offset.
@@ -377,7 +377,7 @@ LayoutUnit RootInlineBox::lineGridSnapAdjustment(LayoutUnit delta) const
firstTextTop = pageLogicalTop + lineGridBox->logicalTop() - lineGrid->borderBefore() - lineGrid->paddingBefore() + lineGridPaginationOrigin;
}
- if (block()->style()->lineGridSnap() == LineGridSnapContain) {
+ if (block()->style()->lineSnap() == LineSnapContain) {
// Compute the desired offset from the text-top of a grid line.
// Look at our height (logicalHeight()).
// Look at the total available height. It's going to be (textBottom - textTop) + (n-1)*(multiple with leading)
@@ -414,7 +414,7 @@ LayoutUnit RootInlineBox::lineGridSnapAdjustment(LayoutUnit delta) const
return result;
// Put ourselves at the top of the next page to force a snap onto the new grid established by that page.
- return lineGridSnapAdjustment(newPageLogicalTop - (blockOffset + lineTopWithLeading()));
+ return lineSnapAdjustment(newPageLogicalTop - (blockOffset + lineTopWithLeading()));
}
GapRects RootInlineBox::lineSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
diff --git a/Source/WebCore/rendering/RootInlineBox.h b/Source/WebCore/rendering/RootInlineBox.h
index fef7ced22..901bcff24 100644
--- a/Source/WebCore/rendering/RootInlineBox.h
+++ b/Source/WebCore/rendering/RootInlineBox.h
@@ -183,7 +183,7 @@ public:
private:
void setHasEllipsisBox(bool hasEllipsisBox) { m_hasEllipsisBoxOrHyphen = hasEllipsisBox; }
- LayoutUnit lineGridSnapAdjustment(LayoutUnit delta = 0) const;
+ LayoutUnit lineSnapAdjustment(LayoutUnit delta = 0) const;
int beforeAnnotationsAdjustment() const;
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLBlock.cpp b/Source/WebCore/rendering/mathml/RenderMathMLBlock.cpp
index 2bdccec2c..167eeb21a 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLBlock.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLBlock.cpp
@@ -49,7 +49,7 @@ bool RenderMathMLBlock::isChildAllowed(RenderObject* child, RenderStyle*) const
return child->node() && child->node()->nodeType() == Node::ELEMENT_NODE;
}
-PassRefPtr<RenderStyle> RenderMathMLBlock::makeBlockStyle()
+PassRefPtr<RenderStyle> RenderMathMLBlock::createBlockStyle()
{
RefPtr<RenderStyle> newStyle = RenderStyle::create();
newStyle->inheritFrom(style());
@@ -57,14 +57,6 @@ PassRefPtr<RenderStyle> RenderMathMLBlock::makeBlockStyle()
return newStyle;
}
-int RenderMathMLBlock::nonOperatorHeight() const
-{
- if (!isRenderMathMLOperator())
- return offsetHeight();
-
- return 0;
-}
-
void RenderMathMLBlock::stretchToHeight(int height)
{
for (RenderObject* current = firstChild(); current; current = current->nextSibling())
@@ -82,7 +74,7 @@ void RenderMathMLBlock::paint(PaintInfo& info, const LayoutPoint& paintOffset)
if (info.context->paintingDisabled() || info.phase != PaintPhaseForeground)
return;
- LayoutPoint adjustedPaintOffset = paintOffset + location();
+ IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset + location());
GraphicsContextStateSaver stateSaver(*info.context);
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLBlock.h b/Source/WebCore/rendering/mathml/RenderMathMLBlock.h
index 4d8184bcf..5d4d780ed 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLBlock.h
+++ b/Source/WebCore/rendering/mathml/RenderMathMLBlock.h
@@ -34,6 +34,8 @@
namespace WebCore {
+class RenderMathMLOperator;
+
class RenderMathMLBlock : public RenderBlock {
public:
RenderMathMLBlock(Node* container);
@@ -43,8 +45,15 @@ public:
virtual bool isRenderMathMLOperator() const { return false; }
virtual bool isRenderMathMLRow() const { return false; }
virtual bool isRenderMathMLMath() const { return false; }
- virtual bool hasBase() const { return false; }
- virtual int nonOperatorHeight() const;
+
+ // MathML defines an "embellished operator" as roughly an <mo> that may have subscripts,
+ // superscripts, underscripts, overscripts, or a denominator (as in d/dx, where "d" is some
+ // differential operator). The padding, precedence, and stretchiness of the base <mo> should
+ // apply to the embellished operator as a whole. unembellishedOperator() checks for being an
+ // embellished operator, and omits any embellishments.
+ // FIXME: We don't yet handle all the cases in the MathML spec. See
+ // https://bugs.webkit.org/show_bug.cgi?id=78617.
+ virtual RenderMathMLOperator* unembellishedOperator() { return 0; }
virtual void stretchToHeight(int height);
#if ENABLE(DEBUG_MATH_LAYOUT)
@@ -70,7 +79,7 @@ protected:
return 0;
}
- virtual PassRefPtr<RenderStyle> makeBlockStyle();
+ virtual PassRefPtr<RenderStyle> createBlockStyle();
private:
virtual const char* renderName() const { return isAnonymous() ? "RenderMathMLBlock (anonymous)" : "RenderMathMLBlock"; }
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLFenced.cpp b/Source/WebCore/rendering/mathml/RenderMathMLFenced.cpp
index 55da1a5ec..c2f67ea93 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLFenced.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLFenced.cpp
@@ -44,8 +44,8 @@ enum Braces { OpeningBraceChar = 0x28, ClosingBraceChar = 0x29 };
static const float gOperatorPadding = 0.1f;
-RenderMathMLFenced::RenderMathMLFenced(Node* fenced)
- : RenderMathMLRow(fenced)
+RenderMathMLFenced::RenderMathMLFenced(Element* element)
+ : RenderMathMLRow(element)
, m_open(OpeningBraceChar)
, m_close(ClosingBraceChar)
{
@@ -63,7 +63,7 @@ void RenderMathMLFenced::updateFromElement()
if (closeValue.length() > 0)
m_close = closeValue[0];
- AtomicString separators = static_cast<Element*>(fenced)->getAttribute(MathMLNames::separatorsAttr);
+ AtomicString separators = fenced->getAttribute(MathMLNames::separatorsAttr);
if (!separators.isNull()) {
StringBuilder characters;
for (unsigned int i = 0; i < separators.length(); i++) {
@@ -80,22 +80,22 @@ void RenderMathMLFenced::updateFromElement()
makeFences();
}
-RefPtr<RenderStyle> RenderMathMLFenced::makeOperatorStyle()
+PassRefPtr<RenderStyle> RenderMathMLFenced::createOperatorStyle()
{
RefPtr<RenderStyle> newStyle = RenderStyle::create();
newStyle->inheritFrom(style());
newStyle->setDisplay(INLINE_BLOCK);
newStyle->setPaddingRight(Length(static_cast<int>(gOperatorPadding * style()->fontSize()), Fixed));
- return newStyle;
+ return newStyle.release();
}
void RenderMathMLFenced::makeFences()
{
RenderObject* openFence = new (renderArena()) RenderMathMLOperator(node(), m_open);
- openFence->setStyle(makeOperatorStyle().release());
+ openFence->setStyle(createOperatorStyle());
RenderBlock::addChild(openFence, firstChild());
RenderObject* closeFence = new (renderArena()) RenderMathMLOperator(node(), m_close);
- closeFence->setStyle(makeOperatorStyle().release());
+ closeFence->setStyle(createOperatorStyle());
RenderBlock::addChild(closeFence);
}
@@ -122,7 +122,7 @@ void RenderMathMLFenced::addChild(RenderObject* child, RenderObject*)
separator = (*m_separators.get())[count - 2];
RenderObject* separatorObj = new (renderArena()) RenderMathMLOperator(node(), separator);
- separatorObj->setStyle(makeOperatorStyle().release());
+ separatorObj->setStyle(createOperatorStyle());
RenderBlock::addChild(separatorObj, lastChild());
}
}
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLFenced.h b/Source/WebCore/rendering/mathml/RenderMathMLFenced.h
index 9707b3ae6..b2bca9971 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLFenced.h
+++ b/Source/WebCore/rendering/mathml/RenderMathMLFenced.h
@@ -34,15 +34,16 @@ namespace WebCore {
class RenderMathMLFenced : public RenderMathMLRow {
public:
- RenderMathMLFenced(Node *fraction);
+ RenderMathMLFenced(Element*);
virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
virtual void updateFromElement();
private:
virtual const char* renderName() const { return "RenderMathMLFenced"; }
+ PassRefPtr<RenderStyle> createOperatorStyle();
void makeFences();
- RefPtr<RenderStyle> makeOperatorStyle();
+
UChar m_open;
UChar m_close;
RefPtr<StringImpl> m_separators;
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp b/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp
index aeaab20f7..dd59bb998 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp
@@ -46,8 +46,8 @@ static const float gLineThick = 3.f;
static const float gFractionBarWidth = 0.05f;
static const float gDenominatorPad = 0.1f;
-RenderMathMLFraction::RenderMathMLFraction(Element* fraction)
- : RenderMathMLBlock(fraction)
+RenderMathMLFraction::RenderMathMLFraction(Element* element)
+ : RenderMathMLBlock(element)
, m_lineThickness(gLineMedium)
{
setChildrenInline(false);
@@ -101,7 +101,7 @@ void RenderMathMLFraction::updateFromElement()
void RenderMathMLFraction::addChild(RenderObject* child, RenderObject* beforeChild)
{
RenderBlock* row = new (renderArena()) RenderMathMLBlock(node());
- RefPtr<RenderStyle> rowStyle = makeBlockStyle();
+ RefPtr<RenderStyle> rowStyle = createBlockStyle();
rowStyle->setTextAlign(CENTER);
Length pad(static_cast<int>(rowStyle->fontSize() * gHorizontalPad), Fixed);
@@ -119,6 +119,17 @@ void RenderMathMLFraction::addChild(RenderObject* child, RenderObject* beforeChi
updateFromElement();
}
+RenderMathMLOperator* RenderMathMLFraction::unembellishedOperator()
+{
+ RenderObject* numeratorWrapper = firstChild();
+ if (!numeratorWrapper)
+ return 0;
+ RenderObject* numerator = numeratorWrapper->firstChild();
+ if (!numerator || !numerator->isRenderMathMLBlock())
+ return 0;
+ return toRenderMathMLBlock(numerator)->unembellishedOperator();
+}
+
void RenderMathMLFraction::layout()
{
updateFromElement();
@@ -153,7 +164,7 @@ void RenderMathMLFraction::paint(PaintInfo& info, const LayoutPoint& paintOffset
verticalOffset = numerator->offsetHeight();
}
- LayoutPoint adjustedPaintOffset = paintOffset + location();
+ IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset + location());
adjustedPaintOffset.setY(adjustedPaintOffset.y() + verticalOffset);
GraphicsContextStateSaver stateSaver(*info.context);
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLFraction.h b/Source/WebCore/rendering/mathml/RenderMathMLFraction.h
index 3971a1e13..4756583b6 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLFraction.h
+++ b/Source/WebCore/rendering/mathml/RenderMathMLFraction.h
@@ -35,15 +35,20 @@ namespace WebCore {
class RenderMathMLFraction : public RenderMathMLBlock {
public:
- RenderMathMLFraction(Element* fraction);
+ RenderMathMLFraction(Element*);
virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
virtual void updateFromElement();
+
+ virtual RenderMathMLOperator* unembellishedOperator();
+
virtual LayoutUnit baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
virtual void paint(PaintInfo&, const LayoutPoint&);
protected:
virtual void layout();
+
private:
virtual const char* renderName() const { return "RenderMathMLFraction"; }
+
float m_lineThickness;
};
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLMath.cpp b/Source/WebCore/rendering/mathml/RenderMathMLMath.cpp
index 006fea31c..15e2bbdbe 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLMath.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLMath.cpp
@@ -35,8 +35,8 @@ namespace WebCore {
using namespace MathMLNames;
-RenderMathMLMath::RenderMathMLMath(Node* math)
- : RenderMathMLRow(math)
+RenderMathMLMath::RenderMathMLMath(Element* element)
+ : RenderMathMLRow(element)
{
}
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLMath.h b/Source/WebCore/rendering/mathml/RenderMathMLMath.h
index a81d5a890..aaa2f4f12 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLMath.h
+++ b/Source/WebCore/rendering/mathml/RenderMathMLMath.h
@@ -34,7 +34,7 @@ namespace WebCore {
class RenderMathMLMath : public RenderMathMLRow {
public:
- RenderMathMLMath(Node* container);
+ RenderMathMLMath(Element*);
virtual bool isRenderMathMLMath() const { return true; }
private:
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLOperator.cpp b/Source/WebCore/rendering/mathml/RenderMathMLOperator.cpp
index 2702c0656..ad11d8bac 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLOperator.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLOperator.cpp
@@ -38,15 +38,15 @@ namespace WebCore {
using namespace MathMLNames;
-RenderMathMLOperator::RenderMathMLOperator(Node* container)
- : RenderMathMLBlock(container)
+RenderMathMLOperator::RenderMathMLOperator(Element* element)
+ : RenderMathMLBlock(element)
, m_stretchHeight(0)
, m_operator(0)
{
}
-RenderMathMLOperator::RenderMathMLOperator(Node* container, UChar operatorChar)
- : RenderMathMLBlock(container)
+RenderMathMLOperator::RenderMathMLOperator(Node* node, UChar operatorChar)
+ : RenderMathMLBlock(node)
, m_stretchHeight(0)
, m_operator(convertHyphenMinusToMinusSign(operatorChar))
{
@@ -139,7 +139,7 @@ void RenderMathMLOperator::updateFromElement()
// This boolean indicates whether stretching is disabled via the markup.
bool stretchDisabled = false;
- // We made need the element later if we can't stretch.
+ // We may need the element later if we can't stretch.
if (node()->nodeType() == Node::ELEMENT_NODE) {
if (Element* mo = static_cast<Element*>(node())) {
AtomicString stretchyAttr = mo->getAttribute(MathMLNames::stretchyAttr);
@@ -282,7 +282,7 @@ void RenderMathMLOperator::updateFromElement()
}
}
-RefPtr<RenderStyle> RenderMathMLOperator::createStackableStyle(int size, int topRelative)
+PassRefPtr<RenderStyle> RenderMathMLOperator::createStackableStyle(int size, int topRelative)
{
RefPtr<RenderStyle> newStyle = RenderStyle::create();
newStyle->inheritFrom(style());
@@ -307,13 +307,13 @@ RefPtr<RenderStyle> RenderMathMLOperator::createStackableStyle(int size, int top
newStyle->setPosition(RelativePosition);
}
- return newStyle;
+ return newStyle.release();
}
RenderBlock* RenderMathMLOperator::createGlyph(UChar glyph, int size, int charRelative, int topRelative)
{
RenderBlock* container = new (renderArena()) RenderMathMLBlock(node());
- container->setStyle(createStackableStyle(size, topRelative).release());
+ container->setStyle(createStackableStyle(size, topRelative));
addChild(container);
RenderBlock* parent = container;
if (charRelative) {
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLOperator.h b/Source/WebCore/rendering/mathml/RenderMathMLOperator.h
index 5ee0660f5..42708724a 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLOperator.h
+++ b/Source/WebCore/rendering/mathml/RenderMathMLOperator.h
@@ -35,9 +35,10 @@ namespace WebCore {
class RenderMathMLOperator : public RenderMathMLBlock {
public:
- RenderMathMLOperator(Node* container);
- RenderMathMLOperator(Node* container, UChar operatorChar);
+ RenderMathMLOperator(Element*);
+ RenderMathMLOperator(Node*, UChar operatorChar);
virtual bool isRenderMathMLOperator() const { return true; }
+ virtual RenderMathMLOperator* unembellishedOperator() { return this; }
virtual void stretchToHeight(int pixelHeight);
virtual void updateFromElement();
virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
@@ -45,7 +46,7 @@ public:
protected:
virtual void layout();
- virtual RefPtr<RenderStyle> createStackableStyle(int size, int topRelative);
+ virtual PassRefPtr<RenderStyle> createStackableStyle(int size, int topRelative);
virtual RenderBlock* createGlyph(UChar glyph, int size = 0, int charRelative = 0, int topRelative = 0);
private:
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLRoot.cpp b/Source/WebCore/rendering/mathml/RenderMathMLRoot.cpp
index 24e79ba7e..07e8ff911 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLRoot.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLRoot.cpp
@@ -64,8 +64,8 @@ const float gRadicalLineThickness = 0.02f;
// Radical thick line thickness (%)
const float gRadicalThickLineThickness = 0.1f;
-RenderMathMLRoot::RenderMathMLRoot(Node *expression)
-: RenderMathMLBlock(expression)
+RenderMathMLRoot::RenderMathMLRoot(Element* element)
+ : RenderMathMLBlock(element)
{
}
@@ -74,7 +74,7 @@ void RenderMathMLRoot::addChild(RenderObject* child, RenderObject* )
if (isEmpty()) {
// Add a block for the index
RenderBlock* block = new (renderArena()) RenderBlock(node());
- RefPtr<RenderStyle> indexStyle = makeBlockStyle();
+ RefPtr<RenderStyle> indexStyle = createBlockStyle();
indexStyle->setDisplay(INLINE_BLOCK);
block->setStyle(indexStyle.release());
RenderBlock::addChild(block);
@@ -82,7 +82,7 @@ void RenderMathMLRoot::addChild(RenderObject* child, RenderObject* )
// FIXME: the wrapping does not seem to be needed anymore.
// this is the base, so wrap it so we can pad it
block = new (renderArena()) RenderBlock(node());
- RefPtr<RenderStyle> baseStyle = makeBlockStyle();
+ RefPtr<RenderStyle> baseStyle = createBlockStyle();
baseStyle->setDisplay(INLINE_BLOCK);
baseStyle->setPaddingLeft(Length(5 * gRadicalWidth , Percent));
block->setStyle(baseStyle.release());
@@ -104,7 +104,7 @@ void RenderMathMLRoot::paint(PaintInfo& info, const LayoutPoint& paintOffset)
if (!firstChild() || !lastChild())
return;
- LayoutPoint adjustedPaintOffset = paintOffset + location();
+ IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset + location());
RenderBoxModelObject* indexBox = toRenderBoxModelObject(lastChild());
@@ -232,7 +232,8 @@ void RenderMathMLRoot::layout()
LayoutUnit indexShift = indexBox->offsetWidth() + topStartShift;
LayoutUnit radicalHeight = static_cast<LayoutUnit>((1 - gRadicalTopLeftPointYPos) * maxHeight);
- LayoutUnit rootMarginTop = radicalHeight + style()->paddingBottom().value() + indexBox->offsetHeight() - (maxHeight + static_cast<LayoutUnit>(gRootPadding * style()->fontSize()));
+ LayoutUnit rootMarginTop = radicalHeight + style()->paddingBottom().value() + indexBox->offsetHeight()
+ - (maxHeight + static_cast<LayoutUnit>(gRootPadding * style()->fontSize()));
style()->setPaddingLeft(Length(indexShift, Fixed));
if (rootMarginTop > 0)
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLRoot.h b/Source/WebCore/rendering/mathml/RenderMathMLRoot.h
index ab3e4f057..19b2ec6ec 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLRoot.h
+++ b/Source/WebCore/rendering/mathml/RenderMathMLRoot.h
@@ -34,7 +34,7 @@ namespace WebCore {
class RenderMathMLRoot : public RenderMathMLBlock {
public:
- RenderMathMLRoot(Node* fraction);
+ RenderMathMLRoot(Element*);
virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
virtual void paint(PaintInfo&, const LayoutPoint&);
protected:
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLRow.cpp b/Source/WebCore/rendering/mathml/RenderMathMLRow.cpp
index 922fa9245..203d194de 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLRow.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLRow.cpp
@@ -36,57 +36,23 @@ namespace WebCore {
using namespace MathMLNames;
-RenderMathMLRow::RenderMathMLRow(Node* row)
- : RenderMathMLBlock(row)
+RenderMathMLRow::RenderMathMLRow(Element* element)
+ : RenderMathMLBlock(element)
{
}
-int RenderMathMLRow::nonOperatorHeight() const
-{
- int maxHeight = 0;
- for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
- if (current->isRenderMathMLBlock()) {
- RenderMathMLBlock* block = toRenderMathMLBlock(current);
- int blockHeight = block->nonOperatorHeight();
- // Check to see if this box has a larger height
- if (blockHeight > maxHeight)
- maxHeight = blockHeight;
- } else if (current->isBoxModelObject()) {
- RenderBoxModelObject* box = toRenderBoxModelObject(current);
- // Check to see if this box has a larger height
- if (box->offsetHeight() > maxHeight)
- maxHeight = box->offsetHeight();
- }
-
- }
- return maxHeight;
-}
-
void RenderMathMLRow::layout()
{
RenderBlock::layout();
LayoutUnit maxHeight = 0;
- int childCount = 0;
- int operatorCount = 0;
// Calculate the non-operator max height of the row.
- LayoutUnit operatorHeight = 0;
for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
- childCount++;
if (current->isRenderMathMLBlock()) {
RenderMathMLBlock* block = toRenderMathMLBlock(current);
- // Check to see if the non-operator block has a greater height.
- if (!block->hasBase() && !block->isRenderMathMLOperator() && block->offsetHeight() > maxHeight)
+ if (!block->unembellishedOperator() && block->offsetHeight() > maxHeight)
maxHeight = block->offsetHeight();
- if (block->hasBase() && block->nonOperatorHeight() > maxHeight)
- maxHeight = block->nonOperatorHeight();
- // If the block is an operator, capture the maximum height and increment the count.
- if (block->isRenderMathMLOperator()) {
- if (block->offsetHeight() > operatorHeight)
- operatorHeight = block->offsetHeight();
- operatorCount++;
- }
} else if (current->isBoxModelObject()) {
RenderBoxModelObject* box = toRenderBoxModelObject(current);
// Check to see if this box has a larger height.
@@ -95,10 +61,8 @@ void RenderMathMLRow::layout()
}
}
- if (childCount > 0 && childCount == operatorCount) {
- // We have only operators and so set the max height to the operator height.
- maxHeight = operatorHeight;
- }
+ if (!maxHeight)
+ maxHeight = style()->fontSize();
// Stretch everything to the same height (blocks can ignore the request).
if (maxHeight > 0) {
@@ -118,17 +82,6 @@ void RenderMathMLRow::layout()
}
}
-
-LayoutUnit RenderMathMLRow::baselinePosition(FontBaseline, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
-{
- if (firstChild() && firstChild()->isRenderMathMLBlock()) {
- RenderMathMLBlock* block = toRenderMathMLBlock(firstChild());
- if (block->isRenderMathMLOperator())
- return block->y() + block->baselinePosition(AlphabeticBaseline, firstLine, direction, linePositionMode);
- }
-
- return RenderBlock::baselinePosition(AlphabeticBaseline, firstLine, direction, linePositionMode);
-}
}
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLRow.h b/Source/WebCore/rendering/mathml/RenderMathMLRow.h
index 73c5a26e5..2a520d07b 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLRow.h
+++ b/Source/WebCore/rendering/mathml/RenderMathMLRow.h
@@ -34,10 +34,8 @@ namespace WebCore {
class RenderMathMLRow : public RenderMathMLBlock {
public:
- RenderMathMLRow(Node* container);
+ RenderMathMLRow(Element*);
virtual bool isRenderMathMLRow() const { return true; }
- virtual int nonOperatorHeight() const;
- virtual LayoutUnit baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
virtual void stretchToHeight(int) {}
protected:
virtual void layout();
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLSquareRoot.cpp b/Source/WebCore/rendering/mathml/RenderMathMLSquareRoot.cpp
index 38ab1c1c0..206426a13 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLSquareRoot.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLSquareRoot.cpp
@@ -61,8 +61,8 @@ const float gRadicalLineThickness = 0.02f;
// Radical thick line thickness (%)
const float gRadicalThickLineThickness = 0.1f;
-RenderMathMLSquareRoot::RenderMathMLSquareRoot(Node *expression)
- : RenderMathMLBlock(expression)
+RenderMathMLSquareRoot::RenderMathMLSquareRoot(Element* element)
+ : RenderMathMLBlock(element)
{
}
@@ -73,7 +73,7 @@ void RenderMathMLSquareRoot::paint(PaintInfo& info, const LayoutPoint& paintOffs
if (info.context->paintingDisabled())
return;
- LayoutPoint adjustedPaintOffset = paintOffset + location();
+ IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset + location());
LayoutUnit maxHeight = 0;
LayoutUnit width = 0;
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLSquareRoot.h b/Source/WebCore/rendering/mathml/RenderMathMLSquareRoot.h
index c8e41cdfb..ad81fdc56 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLSquareRoot.h
+++ b/Source/WebCore/rendering/mathml/RenderMathMLSquareRoot.h
@@ -34,7 +34,7 @@ namespace WebCore {
class RenderMathMLSquareRoot : public RenderMathMLBlock {
public:
- RenderMathMLSquareRoot(Node* fraction);
+ RenderMathMLSquareRoot(Element*);
virtual void paint(PaintInfo&, const LayoutPoint&);
protected:
virtual void layout();
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLSubSup.cpp b/Source/WebCore/rendering/mathml/RenderMathMLSubSup.cpp
index 9a06b0236..631266258 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLSubSup.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLSubSup.cpp
@@ -43,20 +43,30 @@ RenderMathMLSubSup::RenderMathMLSubSup(Element* element)
: RenderMathMLBlock(element)
, m_scripts(0)
{
- // Determine what kind of under/over expression we have by element name
+ // Determine what kind of sub/sup expression we have by element name
if (element->hasLocalName(MathMLNames::msubTag))
m_kind = Sub;
else if (element->hasLocalName(MathMLNames::msupTag))
m_kind = Sup;
- else if (element->hasLocalName(MathMLNames::msubsupTag))
- m_kind = SubSup;
- else
+ else {
+ ASSERT(element->hasLocalName(MathMLNames::msubsupTag));
m_kind = SubSup;
+ }
+}
+
+RenderBoxModelObject* RenderMathMLSubSup::base() const
+{
+ RenderObject* baseWrapper = firstChild();
+ if (!baseWrapper)
+ return 0;
+ RenderObject* base = baseWrapper->firstChild();
+ if (!base || !base->isBoxModelObject())
+ return 0;
+ return toRenderBoxModelObject(base);
}
void RenderMathMLSubSup::addChild(RenderObject* child, RenderObject* beforeChild)
{
-
// Note: The RenderMathMLBlock only allows element children to be added.
Element* childElement = toElement(child->node());
@@ -105,72 +115,49 @@ void RenderMathMLSubSup::addChild(RenderObject* child, RenderObject* beforeChild
}
}
+RenderMathMLOperator* RenderMathMLSubSup::unembellishedOperator()
+{
+ RenderBoxModelObject* base = this->base();
+ if (!base || !base->isRenderMathMLBlock())
+ return 0;
+ return toRenderMathMLBlock(base)->unembellishedOperator();
+}
+
void RenderMathMLSubSup::stretchToHeight(int height)
{
- RenderObject* base = firstChild();
- if (!base || !base->firstChild())
- return;
-
- if (base->firstChild() && base->firstChild()->isRenderMathMLBlock()) {
- RenderMathMLBlock* block = toRenderMathMLBlock(base->firstChild());
- block->stretchToHeight(static_cast<int>(gSubSupStretch * height));
+ RenderBoxModelObject* base = this->base();
+ if (base && base->isRenderMathMLBlock()) {
+ toRenderMathMLBlock(base)->stretchToHeight(static_cast<int>(gSubSupStretch * height));
// Adjust the script placement after we stretch
if (height > 0 && m_kind == SubSup && m_scripts) {
- RenderObject* script = m_scripts->firstChild();
- if (script) {
+ RenderObject* supWrapper = m_scripts->firstChild();
+ if (supWrapper) {
// Calculate the script height without the container margins.
- RenderObject* top = script;
- int topHeight = getBoxModelObjectHeight(top->firstChild());
- int topAdjust = topHeight / gTopAdjustDivisor;
- top->style()->setMarginTop(Length(-topAdjust, Fixed));
- top->style()->setMarginBottom(Length(height - topHeight + topAdjust, Fixed));
- if (top->isBoxModelObject()) {
- RenderBoxModelObject* topBox = toRenderBoxModelObject(top);
- topBox->updateBoxModelInfoFromStyle();
- }
- m_scripts->setNeedsLayout(true);
- setNeedsLayout(true);
+ int supHeight = getBoxModelObjectHeight(supWrapper->firstChild());
+ int supTopAdjust = supHeight / gTopAdjustDivisor;
+ supWrapper->style()->setMarginTop(Length(-supTopAdjust, Fixed));
+ supWrapper->style()->setMarginBottom(Length(height - supHeight + supTopAdjust, Fixed));
+ supWrapper->setNeedsLayout(true);
}
}
-
}
}
-int RenderMathMLSubSup::nonOperatorHeight() const
-{
- if (m_kind == SubSup)
- return static_cast<int>(style()->fontSize()*gSubSupStretch);
- return static_cast<int>(style()->fontSize());
-}
-
-void RenderMathMLSubSup::layout()
+void RenderMathMLSubSup::layout()
{
- if (firstChild())
- firstChild()->setNeedsLayout(true);
- if (m_scripts)
- m_scripts->setNeedsLayout(true);
-
RenderBlock::layout();
- if (m_kind == SubSup) {
- if (RenderObject* base = firstChild()) {
- LayoutUnit maxHeight = 0;
- RenderObject* current = base->firstChild();
- while (current) {
- LayoutUnit height = getBoxModelObjectHeight(current);
- if (height > maxHeight)
- maxHeight = height;
- current = current->nextSibling();
- }
- LayoutUnit heightDiff = m_scripts ? (m_scripts->offsetHeight() - maxHeight) / 2 : 0;
+ if (m_kind == SubSup && m_scripts) {
+ if (RenderBoxModelObject* base = this->base()) {
+ LayoutUnit heightDiff = (m_scripts->offsetHeight() - base->offsetHeight()) / 2;
if (heightDiff < 0)
heightDiff = 0;
- base->style()->setPaddingTop(Length(heightDiff, Fixed));
- base->setNeedsLayout(true);
+ RenderObject* baseWrapper = firstChild();
+ baseWrapper->style()->setPaddingTop(Length(heightDiff, Fixed));
+ baseWrapper->setNeedsLayout(true);
+ RenderBlock::layout();
}
- setNeedsLayout(true);
- RenderBlock::layout();
}
}
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLSubSup.h b/Source/WebCore/rendering/mathml/RenderMathMLSubSup.h
index 2ba466cb4..9c7d02c89 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLSubSup.h
+++ b/Source/WebCore/rendering/mathml/RenderMathMLSubSup.h
@@ -34,10 +34,10 @@ namespace WebCore {
class RenderMathMLSubSup : public RenderMathMLBlock {
public:
- RenderMathMLSubSup(Element* fraction);
+ RenderMathMLSubSup(Element*);
virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
- virtual bool hasBase() const { return true; }
- virtual int nonOperatorHeight() const;
+
+ virtual RenderMathMLOperator* unembellishedOperator();
virtual void stretchToHeight(int pixelHeight);
virtual LayoutUnit baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
@@ -47,6 +47,10 @@ protected:
private:
virtual const char* renderName() const { return "RenderMathMLSubSup"; }
+ // Omit our subscript and/or superscript. This may return 0 for a non-MathML base (which
+ // won't occur in valid MathML).
+ RenderBoxModelObject* base() const;
+
enum SubSupType { Sub, Sup, SubSup };
SubSupType m_kind;
RenderBlock* m_scripts;
@@ -57,4 +61,3 @@ private:
#endif // ENABLE(MATHML)
#endif // RenderMathMLSubSup_h
-
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.cpp b/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.cpp
index 75911036a..0621cd6dd 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.cpp
@@ -38,27 +38,37 @@ using namespace MathMLNames;
static const double gOverSpacingAdjustment = 0.5;
-RenderMathMLUnderOver::RenderMathMLUnderOver(Node* expression)
- : RenderMathMLBlock(expression)
+RenderMathMLUnderOver::RenderMathMLUnderOver(Element* element)
+ : RenderMathMLBlock(element)
{
- Element* element = static_cast<Element*>(expression);
// Determine what kind of under/over expression we have by element name
-
if (element->hasLocalName(MathMLNames::munderTag))
m_kind = Under;
else if (element->hasLocalName(MathMLNames::moverTag))
m_kind = Over;
- else if (element->hasLocalName(MathMLNames::munderoverTag))
+ else {
+ ASSERT(element->hasLocalName(MathMLNames::munderoverTag));
m_kind = UnderOver;
- else
- m_kind = Under;
-
+ }
+}
+
+RenderBoxModelObject* RenderMathMLUnderOver::base() const
+{
+ RenderObject* baseWrapper = firstChild();
+ if ((m_kind == Over || m_kind == UnderOver) && baseWrapper)
+ baseWrapper = baseWrapper->nextSibling();
+ if (!baseWrapper)
+ return 0;
+ RenderObject* base = baseWrapper->firstChild();
+ if (!base || !base->isBoxModelObject())
+ return 0;
+ return toRenderBoxModelObject(base);
}
void RenderMathMLUnderOver::addChild(RenderObject* child, RenderObject* beforeChild)
{
RenderMathMLBlock* row = new (renderArena()) RenderMathMLBlock(node());
- RefPtr<RenderStyle> rowStyle = makeBlockStyle();
+ RefPtr<RenderStyle> rowStyle = createBlockStyle();
row->setStyle(rowStyle.release());
row->setIsAnonymous(true);
@@ -109,6 +119,14 @@ void RenderMathMLUnderOver::addChild(RenderObject* child, RenderObject* beforeCh
row->addChild(child);
}
+RenderMathMLOperator* RenderMathMLUnderOver::unembellishedOperator()
+{
+ RenderBoxModelObject* base = this->base();
+ if (!base || !base->isRenderMathMLBlock())
+ return 0;
+ return toRenderMathMLBlock(base)->unembellishedOperator();
+}
+
inline int getOffsetHeight(RenderObject* obj)
{
if (obj->isBoxModelObject()) {
@@ -121,21 +139,7 @@ inline int getOffsetHeight(RenderObject* obj)
void RenderMathMLUnderOver::stretchToHeight(int height)
{
-
- RenderObject* base = firstChild();
- if (!base)
- return;
-
- // For over or underover, the base is the sibling of the first child
- if (m_kind != Under)
- base = base->nextSibling();
-
- if (!base)
- return;
-
- // use the child of the row which is the actual base
- base = base->firstChild();
-
+ RenderBoxModelObject* base = this->base();
if (base && base->isRenderMathMLBlock()) {
RenderMathMLBlock* block = toRenderMathMLBlock(base);
block->stretchToHeight(height);
@@ -275,21 +279,6 @@ LayoutUnit RenderMathMLUnderOver::baselinePosition(FontBaseline, bool firstLine,
return baseline;
}
-
-int RenderMathMLUnderOver::nonOperatorHeight() const
-{
- int nonOperators = 0;
- for (RenderObject* current = firstChild(); current; current = current->nextSibling()) {
- if (current->firstChild() && current->firstChild()->isRenderMathMLBlock()) {
- RenderMathMLBlock* block = toRenderMathMLBlock(current->firstChild());
- if (!block->isRenderMathMLOperator())
- nonOperators += getOffsetHeight(current);
- } else
- nonOperators += getOffsetHeight(current);
- }
- return nonOperators;
-}
-
}
#endif // ENABLE(MATHML)
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.h b/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.h
index 2fe619821..e25e94768 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.h
+++ b/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.h
@@ -34,16 +34,21 @@ namespace WebCore {
class RenderMathMLUnderOver : public RenderMathMLBlock {
public:
- RenderMathMLUnderOver(Node* expression);
+ RenderMathMLUnderOver(Element*);
virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
+
+ virtual RenderMathMLOperator* unembellishedOperator();
virtual void layout();
- virtual bool hasBase() const { return true; }
- virtual int nonOperatorHeight() const;
virtual LayoutUnit baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
virtual void stretchToHeight(int pixelHeight);
+
private:
virtual const char* renderName() const { return "RenderMathMLUnderOver"; }
+ // Omit our underscript and/or overscript. This may return 0 for a non-MathML base (which
+ // won't occur in valid MathML).
+ RenderBoxModelObject* base() const;
+
enum UnderOverType { Under, Over, UnderOver };
UnderOverType m_kind;
};
diff --git a/Source/WebCore/rendering/style/RenderStyle.cpp b/Source/WebCore/rendering/style/RenderStyle.cpp
index 08bfbf90f..c62b3b198 100644
--- a/Source/WebCore/rendering/style/RenderStyle.cpp
+++ b/Source/WebCore/rendering/style/RenderStyle.cpp
@@ -466,7 +466,8 @@ StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedCon
|| rareInheritedData->textEmphasisCustomMark != other->rareInheritedData->textEmphasisCustomMark
|| rareInheritedData->m_lineBoxContain != other->rareInheritedData->m_lineBoxContain
|| rareInheritedData->m_lineGrid != other->rareInheritedData->m_lineGrid
- || rareInheritedData->m_lineGridSnap != other->rareInheritedData->m_lineGridSnap)
+ || rareInheritedData->m_lineSnap != other->rareInheritedData->m_lineSnap
+ || rareInheritedData->m_lineAlign != other->rareInheritedData->m_lineAlign)
return StyleDifferenceLayout;
if (!rareInheritedData->shadowDataEquivalent(*other->rareInheritedData.get()))
@@ -886,7 +887,7 @@ static float calcConstraintScaleFor(const IntRect& rect, const RoundedRect::Radi
RoundedRect RenderStyle::getRoundedBorderFor(const LayoutRect& borderRect, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const
{
- RoundedRect roundedRect(borderRect);
+ RoundedRect roundedRect(pixelSnappedIntRect(borderRect));
if (hasBorderRadius()) {
RoundedRect::Radii radii = calcRadiiFor(surround->border, borderRect.size());
radii.scale(calcConstraintScaleFor(borderRect, radii));
@@ -915,7 +916,7 @@ RoundedRect RenderStyle::getRoundedInnerBorderFor(const LayoutRect& borderRect,
borderRect.width() - leftWidth - rightWidth,
borderRect.height() - topWidth - bottomWidth);
- RoundedRect roundedRect(innerRect);
+ RoundedRect roundedRect(pixelSnappedIntRect(innerRect));
if (hasBorderRadius()) {
RoundedRect::Radii radii = getRoundedBorderFor(borderRect).radii();
diff --git a/Source/WebCore/rendering/style/RenderStyle.h b/Source/WebCore/rendering/style/RenderStyle.h
index 74fae1daf..647d3e9fc 100644
--- a/Source/WebCore/rendering/style/RenderStyle.h
+++ b/Source/WebCore/rendering/style/RenderStyle.h
@@ -791,9 +791,9 @@ public:
float aspectRatioNumerator() const { return rareNonInheritedData->m_aspectRatioNumerator; }
EBoxAlignment boxAlign() const { return static_cast<EBoxAlignment>(rareNonInheritedData->m_deprecatedFlexibleBox->align); }
EBoxDirection boxDirection() const { return static_cast<EBoxDirection>(inherited_flags._box_direction); }
- float boxFlex() { return rareNonInheritedData->m_deprecatedFlexibleBox->flex; }
+ float boxFlex() const { return rareNonInheritedData->m_deprecatedFlexibleBox->flex; }
unsigned int boxFlexGroup() const { return rareNonInheritedData->m_deprecatedFlexibleBox->flex_group; }
- EBoxLines boxLines() { return static_cast<EBoxLines>(rareNonInheritedData->m_deprecatedFlexibleBox->lines); }
+ EBoxLines boxLines() const { return static_cast<EBoxLines>(rareNonInheritedData->m_deprecatedFlexibleBox->lines); }
unsigned int boxOrdinalGroup() const { return rareNonInheritedData->m_deprecatedFlexibleBox->ordinal_group; }
EBoxOrient boxOrient() const { return static_cast<EBoxOrient>(rareNonInheritedData->m_deprecatedFlexibleBox->orient); }
EBoxPack boxPack() const { return static_cast<EBoxPack>(rareNonInheritedData->m_deprecatedFlexibleBox->pack); }
@@ -903,7 +903,8 @@ public:
RegionOverflow regionOverflow() const { return static_cast<RegionOverflow>(rareNonInheritedData->m_regionOverflow); }
const AtomicString& lineGrid() const { return rareInheritedData->m_lineGrid; }
- LineGridSnap lineGridSnap() const { return static_cast<LineGridSnap>(rareInheritedData->m_lineGridSnap); }
+ LineSnap lineSnap() const { return static_cast<LineSnap>(rareInheritedData->m_lineSnap); }
+ LineAlign lineAlign() const { return static_cast<LineAlign>(rareInheritedData->m_lineAlign); }
WrapFlow wrapFlow() const { return static_cast<WrapFlow>(rareNonInheritedData->m_wrapFlow); }
WrapThrough wrapThrough() const { return static_cast<WrapThrough>(rareNonInheritedData->m_wrapThrough); }
@@ -943,6 +944,9 @@ public:
#if ENABLE(TOUCH_EVENTS)
Color tapHighlightColor() const { return rareInheritedData->tapHighlightColor; }
#endif
+#if ENABLE(OVERFLOW_SCROLLING)
+ bool useTouchOverflowScrolling() const { return rareInheritedData->useTouchOverflowScrolling; }
+#endif
bool textSizeAdjust() const { return rareInheritedData->textSizeAdjust; }
ETextSecurity textSecurity() const { return static_cast<ETextSecurity>(rareInheritedData->textSecurity); }
@@ -1302,7 +1306,8 @@ public:
// End CSS3 Setters
void setLineGrid(const AtomicString& lineGrid) { SET_VAR(rareInheritedData, m_lineGrid, lineGrid); }
- void setLineGridSnap(LineGridSnap lineGridSnap) { SET_VAR(rareInheritedData, m_lineGridSnap, lineGridSnap); }
+ void setLineSnap(LineSnap lineSnap) { SET_VAR(rareInheritedData, m_lineSnap, lineSnap); }
+ void setLineAlign(LineAlign lineAlign) { SET_VAR(rareInheritedData, m_lineAlign, lineAlign); }
void setFlowThread(const AtomicString& flowThread) { SET_VAR(rareNonInheritedData, m_flowThread, flowThread); }
void setRegionThread(const AtomicString& regionThread) { SET_VAR(rareNonInheritedData, m_regionThread, regionThread); }
@@ -1347,6 +1352,9 @@ public:
#if ENABLE(TOUCH_EVENTS)
void setTapHighlightColor(const Color& c) { SET_VAR(rareInheritedData, tapHighlightColor, c); }
#endif
+#if ENABLE(OVERFLOW_SCROLLING)
+ void setUseTouchOverflowScrolling(bool v) { SET_VAR(rareInheritedData, useTouchOverflowScrolling, v); }
+#endif
bool setTextSizeAdjust(bool);
void setTextSecurity(ETextSecurity aTextSecurity) { SET_VAR(rareInheritedData, textSecurity, aTextSecurity); }
@@ -1532,8 +1540,8 @@ public:
static Length initialPadding() { return Length(Fixed); }
static Length initialTextIndent() { return Length(Fixed); }
static EVerticalAlign initialVerticalAlign() { return BASELINE; }
- static int initialWidows() { return 2; }
- static int initialOrphans() { return 2; }
+ static short initialWidows() { return 2; }
+ static short initialOrphans() { return 2; }
static Length initialLineHeight() { return Length(-100.0, Percent); }
static ETextAlign initialTextAlign() { return TAAUTO; }
static ETextDecoration initialTextDecoration() { return TDNONE; }
@@ -1546,8 +1554,8 @@ public:
static EBoxOrient initialBoxOrient() { return HORIZONTAL; }
static EBoxPack initialBoxPack() { return Start; }
static float initialBoxFlex() { return 0.0f; }
- static int initialBoxFlexGroup() { return 1; }
- static int initialBoxOrdinalGroup() { return 1; }
+ static unsigned int initialBoxFlexGroup() { return 1; }
+ static unsigned int initialBoxOrdinalGroup() { return 1; }
static EBoxSizing initialBoxSizing() { return CONTENT_BOX; }
static StyleReflection* initialBoxReflect() { return 0; }
static float initialFlexboxWidthPositiveFlex() { return 0; }
@@ -1559,7 +1567,7 @@ public:
static EFlexAlign initialFlexAlign() { return AlignStretch; }
static EFlexAlign initialFlexItemAlign() { return AlignAuto; }
static EFlexDirection initialFlexDirection() { return FlowRow; }
- static EFlexWrap initialFlexWrap() { return FlexNoWrap; }
+ static EFlexWrap initialFlexWrap() { return FlexWrapNone; }
static int initialMarqueeLoopCount() { return -1; }
static int initialMarqueeSpeed() { return 85; }
static Length initialMarqueeIncrement() { return Length(6, Fixed); }
@@ -1631,7 +1639,8 @@ public:
#endif
static const AtomicString& initialLineGrid() { return nullAtom; }
- static LineGridSnap initialLineGridSnap() { return LineGridSnapNone; }
+ static LineSnap initialLineSnap() { return LineSnapNone; }
+ static LineAlign initialLineAlign() { return LineAlignNone; }
static const AtomicString& initialFlowThread() { return nullAtom; }
static const AtomicString& initialRegionThread() { return nullAtom; }
@@ -1647,6 +1656,9 @@ public:
#if ENABLE(TOUCH_EVENTS)
static Color initialTapHighlightColor();
#endif
+#if ENABLE(OVERFLOW_SCROLLING)
+ static bool initialUseTouchOverflowScrolling() { return false; }
+#endif
#if ENABLE(DASHBOARD_SUPPORT)
static const Vector<StyleDashboardRegion>& initialDashboardRegions();
static const Vector<StyleDashboardRegion>& noneDashboardRegions();
diff --git a/Source/WebCore/rendering/style/RenderStyleConstants.h b/Source/WebCore/rendering/style/RenderStyleConstants.h
index 0ce3d8886..aee10813a 100644
--- a/Source/WebCore/rendering/style/RenderStyleConstants.h
+++ b/Source/WebCore/rendering/style/RenderStyleConstants.h
@@ -171,7 +171,7 @@ enum EBoxDirection { BNORMAL, BREVERSE };
enum EFlexPack { PackStart, PackEnd, PackCenter, PackJustify, PackDistribute };
enum EFlexAlign { AlignAuto, AlignStart, AlignEnd, AlignCenter, AlignStretch, AlignBaseline };
enum EFlexDirection { FlowRow, FlowRowReverse, FlowColumn, FlowColumnReverse };
-enum EFlexWrap { FlexNoWrap, FlexWrap, FlexWrapReverse };
+enum EFlexWrap { FlexWrapNone, FlexWrap, FlexWrapReverse };
enum ETextSecurity {
TSNONE, TSDISC, TSCIRCLE, TSSQUARE
@@ -454,7 +454,9 @@ enum RegionOverflow { AutoRegionOverflow, BreakRegionOverflow };
enum ColumnAxis { HorizontalColumnAxis, VerticalColumnAxis, AutoColumnAxis };
-enum LineGridSnap { LineGridSnapNone, LineGridSnapBaseline, LineGridSnapContain };
+enum LineSnap { LineSnapNone, LineSnapBaseline, LineSnapContain };
+
+enum LineAlign { LineAlignNone, LineAlignEdges };
enum WrapFlow { WrapFlowAuto, WrapFlowBoth, WrapFlowLeft, WrapFlowRight, WrapFlowMaximum, WrapFlowClear };
diff --git a/Source/WebCore/rendering/style/StyleCachedImage.cpp b/Source/WebCore/rendering/style/StyleCachedImage.cpp
index 1a7d9ef10..a7a1996fa 100644
--- a/Source/WebCore/rendering/style/StyleCachedImage.cpp
+++ b/Source/WebCore/rendering/style/StyleCachedImage.cpp
@@ -24,11 +24,22 @@
#include "config.h"
#include "StyleCachedImage.h"
-#include "CachedImage.h"
#include "RenderObject.h"
namespace WebCore {
+StyleCachedImage::StyleCachedImage(CachedImage* image)
+ : m_image(image)
+{
+ m_isCachedImage = true;
+ m_image->addClient(this);
+}
+
+StyleCachedImage::~StyleCachedImage()
+{
+ m_image->removeClient(this);
+}
+
PassRefPtr<CSSValue> StyleCachedImage::cssValue() const
{
return CSSPrimitiveValue::create(m_image->url(), CSSPrimitiveValue::CSS_URI);
diff --git a/Source/WebCore/rendering/style/StyleCachedImage.h b/Source/WebCore/rendering/style/StyleCachedImage.h
index 06dfb25a6..c9913fd82 100644
--- a/Source/WebCore/rendering/style/StyleCachedImage.h
+++ b/Source/WebCore/rendering/style/StyleCachedImage.h
@@ -24,16 +24,18 @@
#ifndef StyleCachedImage_h
#define StyleCachedImage_h
+#include "CachedImage.h"
#include "CachedResourceHandle.h"
#include "StyleImage.h"
namespace WebCore {
-class CachedImage;
-
-class StyleCachedImage : public StyleImage {
+class StyleCachedImage : public StyleImage, private CachedImageClient {
+ WTF_MAKE_FAST_ALLOCATED;
public:
static PassRefPtr<StyleCachedImage> create(CachedImage* image) { return adoptRef(new StyleCachedImage(image)); }
+ virtual ~StyleCachedImage();
+
virtual WrappedImagePtr data() const { return m_image.get(); }
virtual PassRefPtr<CSSValue> cssValue() const;
@@ -54,11 +56,7 @@ public:
virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const;
private:
- StyleCachedImage(CachedImage* image)
- : m_image(image)
- {
- m_isCachedImage = true;
- }
+ explicit StyleCachedImage(CachedImage*);
CachedResourceHandle<CachedImage> m_image;
};
diff --git a/Source/WebCore/rendering/style/StyleRareInheritedData.cpp b/Source/WebCore/rendering/style/StyleRareInheritedData.cpp
index 9dda82d8b..5d73793ce 100644
--- a/Source/WebCore/rendering/style/StyleRareInheritedData.cpp
+++ b/Source/WebCore/rendering/style/StyleRareInheritedData.cpp
@@ -53,7 +53,11 @@ StyleRareInheritedData::StyleRareInheritedData()
, textEmphasisPosition(TextEmphasisPositionOver)
, m_lineBoxContain(RenderStyle::initialLineBoxContain())
, m_imageRendering(RenderStyle::initialImageRendering())
- , m_lineGridSnap(RenderStyle::initialLineGridSnap())
+ , m_lineSnap(RenderStyle::initialLineSnap())
+ , m_lineAlign(RenderStyle::initialLineAlign())
+#if ENABLE(OVERFLOW_SCROLLING)
+ , useTouchOverflowScrolling(RenderStyle::initialUseTouchOverflowScrolling())
+#endif
, hyphenationLimitBefore(-1)
, hyphenationLimitAfter(-1)
, hyphenationLimitLines(-1)
@@ -97,7 +101,11 @@ StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedData& o)
, textEmphasisPosition(o.textEmphasisPosition)
, m_lineBoxContain(o.m_lineBoxContain)
, m_imageRendering(o.m_imageRendering)
- , m_lineGridSnap(o.m_lineGridSnap)
+ , m_lineSnap(o.m_lineSnap)
+ , m_lineAlign(o.m_lineAlign)
+#if ENABLE(OVERFLOW_SCROLLING)
+ , useTouchOverflowScrolling(o.useTouchOverflowScrolling)
+#endif
, hyphenationString(o.hyphenationString)
, hyphenationLimitBefore(o.hyphenationLimitBefore)
, hyphenationLimitAfter(o.hyphenationLimitAfter)
@@ -149,6 +157,9 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const
&& wordWrap == o.wordWrap
&& nbspMode == o.nbspMode
&& khtmlLineBreak == o.khtmlLineBreak
+#if ENABLE(OVERFLOW_SCROLLING)
+ && useTouchOverflowScrolling == o.useTouchOverflowScrolling
+#endif
&& textSizeAdjust == o.textSizeAdjust
&& resize == o.resize
&& userSelect == o.userSelect
@@ -168,7 +179,8 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const
&& QuotesData::equal(quotes.get(), o.quotes.get())
&& m_lineGrid == o.m_lineGrid
&& m_imageRendering == o.m_imageRendering
- && m_lineGridSnap == o.m_lineGridSnap;
+ && m_lineSnap == o.m_lineSnap
+ && m_lineAlign == o.m_lineAlign;
}
bool StyleRareInheritedData::shadowDataEquivalent(const StyleRareInheritedData& o) const
diff --git a/Source/WebCore/rendering/style/StyleRareInheritedData.h b/Source/WebCore/rendering/style/StyleRareInheritedData.h
index fd5796936..570dbb573 100644
--- a/Source/WebCore/rendering/style/StyleRareInheritedData.h
+++ b/Source/WebCore/rendering/style/StyleRareInheritedData.h
@@ -91,7 +91,11 @@ public:
unsigned m_lineBoxContain: 7; // LineBoxContain
// CSS Image Values Level 3
unsigned m_imageRendering : 2; // EImageRendering
- unsigned m_lineGridSnap : 2; // LineGridSnap
+ unsigned m_lineSnap : 2; // LineSnap
+ unsigned m_lineAlign : 1; // LineAlign
+#if ENABLE(OVERFLOW_SCROLLING)
+ unsigned useTouchOverflowScrolling: 1;
+#endif
AtomicString hyphenationString;
short hyphenationLimitBefore;
diff --git a/Source/WebCore/rendering/svg/RenderSVGContainer.h b/Source/WebCore/rendering/svg/RenderSVGContainer.h
index c7d9f205f..b3324703c 100644
--- a/Source/WebCore/rendering/svg/RenderSVGContainer.h
+++ b/Source/WebCore/rendering/svg/RenderSVGContainer.h
@@ -41,6 +41,7 @@ public:
virtual void paint(PaintInfo&, const LayoutPoint&);
virtual void setNeedsBoundariesUpdate() { m_needsBoundariesUpdate = true; }
+ virtual bool didTransformToRootUpdate() { return false; }
protected:
virtual RenderObjectChildList* virtualChildren() { return children(); }
diff --git a/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp b/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
index 74facc3cf..591316291 100644
--- a/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
@@ -267,6 +267,8 @@ void RenderSVGInlineText::computeNewScaledFontForStyle(RenderObject* renderer, c
}
FontDescription fontDescription(style->fontDescription());
+
+ // FIXME: We need to better handle the case when we compute very small fonts below (below 1pt).
fontDescription.setComputedSize(CSSStyleSelector::getComputedSizeFromSpecifiedSize(document, scalingFactor, fontDescription.isAbsoluteSize(), fontDescription.computedSize(), DoNotUseSmartMinimumForFontSize));
scaledFont = Font(fontDescription, 0, 0);
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp
index 5adb29950..2e03e9f59 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp
@@ -38,7 +38,7 @@ static inline SVGDocumentExtensions* svgExtensionsFromNode(Node* node)
RenderSVGResourceContainer::RenderSVGResourceContainer(SVGStyledElement* node)
: RenderSVGHiddenContainer(node)
- , m_id(node->hasID() ? node->getIdAttribute() : nullAtom)
+ , m_id(node->getIdAttribute())
, m_registered(false)
, m_isInvalidating(false)
{
diff --git a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
index ba821cca2..7baa4fc38 100644
--- a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
@@ -306,7 +306,7 @@ void RenderSVGRoot::buildLocalToBorderBoxTransform()
float scale = style()->effectiveZoom();
FloatPoint translate = svg->currentTranslate();
LayoutSize borderAndPadding(borderLeft() + paddingLeft(), borderTop() + paddingTop());
- m_localToBorderBoxTransform = svg->viewBoxToViewTransform(width() / scale, height() / scale);
+ m_localToBorderBoxTransform = svg->viewBoxToViewTransform(contentWidth() / scale, contentHeight() / scale);
if (borderAndPadding.isEmpty() && scale == 1 && translate == FloatPoint::zero())
return;
m_localToBorderBoxTransform = AffineTransform(scale, 0, 0, scale, borderAndPadding.width() + translate.x(), borderAndPadding.height() + translate.y()) * m_localToBorderBoxTransform;
diff --git a/Source/WebCore/rendering/svg/RenderSVGRoot.h b/Source/WebCore/rendering/svg/RenderSVGRoot.h
index cb7a1b2e0..701137f44 100644
--- a/Source/WebCore/rendering/svg/RenderSVGRoot.h
+++ b/Source/WebCore/rendering/svg/RenderSVGRoot.h
@@ -56,7 +56,6 @@ public:
private:
virtual RenderObjectChildList* virtualChildren() { return children(); }
virtual const RenderObjectChildList* virtualChildren() const { return children(); }
- virtual bool canHaveChildren() const { return true; }
virtual bool isSVGRoot() const { return true; }
virtual const char* renderName() const { return "RenderSVGRoot"; }
@@ -87,6 +86,7 @@ private:
virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&, bool* wasFixed = 0) const;
virtual bool canBeSelectionLeaf() const { return false; }
+ virtual bool canHaveChildren() const { return true; }
void updateCachedBoundaries();
void buildLocalToBorderBoxTransform();
diff --git a/Source/WebCore/rendering/svg/RenderSVGText.cpp b/Source/WebCore/rendering/svg/RenderSVGText.cpp
index ebf92e569..d9cdeccdf 100644
--- a/Source/WebCore/rendering/svg/RenderSVGText.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGText.cpp
@@ -58,6 +58,7 @@ RenderSVGText::RenderSVGText(SVGTextElement* node)
, m_needsReordering(false)
, m_needsPositioningValuesUpdate(true)
, m_needsTransformUpdate(true)
+ , m_needsTextMetricsUpdate(true)
{
}
@@ -208,11 +209,13 @@ void RenderSVGText::layout()
updateCachedBoundariesInParents = true;
}
- // If the root layout size changed (eg. window size changes) or the positioning values change, recompute the on-screen font size.
- if (SVGRenderSupport::findTreeRootObject(this)->isLayoutSizeChanged()) {
+ // If the root layout size changed (eg. window size changes) or the positioning values change
+ // or the transform to the root context has changed then recompute the on-screen font size.
+ if (m_needsTextMetricsUpdate || SVGRenderSupport::findTreeRootObject(this)->isLayoutSizeChanged()) {
recursiveUpdateScaledFont(this);
rebuildLayoutAttributes(true);
updateCachedBoundariesInParents = true;
+ m_needsTextMetricsUpdate = false;
}
if (m_needsPositioningValuesUpdate) {
diff --git a/Source/WebCore/rendering/svg/RenderSVGText.h b/Source/WebCore/rendering/svg/RenderSVGText.h
index 864101695..7b0b5efa8 100644
--- a/Source/WebCore/rendering/svg/RenderSVGText.h
+++ b/Source/WebCore/rendering/svg/RenderSVGText.h
@@ -41,6 +41,7 @@ public:
void setNeedsPositioningValuesUpdate() { m_needsPositioningValuesUpdate = true; }
virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
+ void setNeedsTextMetricsUpdate() { m_needsTextMetricsUpdate = true; }
virtual FloatRect repaintRectInLocalCoordinates() const;
static RenderSVGText* locateRenderSVGTextAncestor(RenderObject*);
@@ -90,6 +91,7 @@ private:
bool m_needsReordering : 1;
bool m_needsPositioningValuesUpdate : 1;
bool m_needsTransformUpdate : 1;
+ bool m_needsTextMetricsUpdate : 1;
AffineTransform m_localTransform;
SVGTextLayoutAttributesBuilder m_layoutAttributesBuilder;
Vector<SVGTextLayoutAttributes*> m_layoutAttributes;
diff --git a/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.cpp
index 1db6365b2..0a62f6885 100644
--- a/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.cpp
@@ -25,6 +25,7 @@
#include "RenderSVGTransformableContainer.h"
#include "SVGNames.h"
+#include "SVGRenderSupport.h"
#include "SVGShadowTreeElements.h"
#include "SVGStyledTransformableElement.h"
@@ -33,6 +34,7 @@ namespace WebCore {
RenderSVGTransformableContainer::RenderSVGTransformableContainer(SVGStyledTransformableElement* node)
: RenderSVGContainer(node)
, m_needsTransformUpdate(true)
+ , m_didTransformToRootUpdate(false)
{
}
@@ -41,6 +43,7 @@ bool RenderSVGTransformableContainer::calculateLocalTransform()
SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
bool needsUpdate = m_needsTransformUpdate;
+ m_didTransformToRootUpdate = m_needsTransformUpdate || SVGRenderSupport::transformToRootChanged(parent());
if (needsUpdate) {
m_localTransform = element->animatedLocalTransform();
m_needsTransformUpdate = false;
diff --git a/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.h b/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.h
index 401bfa858..c9c607ba2 100644
--- a/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.h
+++ b/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.h
@@ -31,14 +31,17 @@ class RenderSVGTransformableContainer : public RenderSVGContainer {
public:
explicit RenderSVGTransformableContainer(SVGStyledTransformableElement*);
+ virtual bool isSVGTransformableContainer() const { return true; }
virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
+ virtual bool didTransformToRootUpdate() { return m_didTransformToRootUpdate; }
private:
virtual bool calculateLocalTransform();
virtual AffineTransform localTransform() const { return m_localTransform; }
bool m_needsTransformUpdate : 1;
+ bool m_didTransformToRootUpdate : 1;
AffineTransform m_localTransform;
};
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp
index 1021aff00..3e0e3e4d9 100644
--- a/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp
@@ -34,7 +34,9 @@ namespace WebCore {
RenderSVGViewportContainer::RenderSVGViewportContainer(SVGStyledElement* node)
: RenderSVGContainer(node)
+ , m_didTransformToRootUpdate(false)
, m_isLayoutSizeChanged(false)
+ , m_needsTransformUpdate(true)
{
}
@@ -63,8 +65,21 @@ void RenderSVGViewportContainer::calcViewport()
SVGLengthContext lengthContext(element);
m_viewport = FloatRect(svg->x().value(lengthContext), svg->y().value(lengthContext), svg->width().value(lengthContext), svg->height().value(lengthContext));
- if (oldViewport != m_viewport)
+ if (oldViewport != m_viewport) {
+ m_didTransformToRootUpdate = true;
setNeedsBoundariesUpdate();
+ setNeedsTransformUpdate();
+ }
+}
+
+bool RenderSVGViewportContainer::calculateLocalTransform()
+{
+ if (!m_needsTransformUpdate)
+ return false;
+
+ m_localToParentTransform = AffineTransform::translation(m_viewport.x(), m_viewport.y()) * viewportTransform();
+ m_needsTransformUpdate = false;
+ return true;
}
AffineTransform RenderSVGViewportContainer::viewportTransform() const
@@ -77,14 +92,6 @@ AffineTransform RenderSVGViewportContainer::viewportTransform() const
return AffineTransform();
}
-const AffineTransform& RenderSVGViewportContainer::localToParentTransform() const
-{
- m_localToParentTransform = AffineTransform::translation(m_viewport.x(), m_viewport.y()) * viewportTransform();
- return m_localToParentTransform;
- // If this class were ever given a localTransform(), then the above would read:
- // return viewportTranslation * localTransform() * viewportTransform()
-}
-
bool RenderSVGViewportContainer::pointIsInsideViewportClip(const FloatPoint& pointInParent)
{
// Respect the viewport clip (which is in parent coords)
diff --git a/Source/WebCore/rendering/svg/RenderSVGViewportContainer.h b/Source/WebCore/rendering/svg/RenderSVGViewportContainer.h
index 808d6727b..b748fe6f0 100644
--- a/Source/WebCore/rendering/svg/RenderSVGViewportContainer.h
+++ b/Source/WebCore/rendering/svg/RenderSVGViewportContainer.h
@@ -36,8 +36,10 @@ public:
FloatRect viewport() const { return m_viewport; }
bool isLayoutSizeChanged() const { return m_isLayoutSizeChanged; }
+ virtual bool didTransformToRootUpdate() { return m_didTransformToRootUpdate; }
virtual void determineIfLayoutSizeChanged();
+ virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
private:
virtual bool isSVGContainer() const { return true; }
@@ -45,16 +47,19 @@ private:
virtual const char* renderName() const { return "RenderSVGViewportContainer"; }
AffineTransform viewportTransform() const;
- virtual const AffineTransform& localToParentTransform() const;
+ virtual const AffineTransform& localToParentTransform() const { return m_localToParentTransform; }
virtual void calcViewport();
+ virtual bool calculateLocalTransform();
virtual void applyViewportClip(PaintInfo&);
virtual bool pointIsInsideViewportClip(const FloatPoint& pointInParent);
FloatRect m_viewport;
mutable AffineTransform m_localToParentTransform;
+ bool m_didTransformToRootUpdate : 1;
bool m_isLayoutSizeChanged : 1;
+ bool m_needsTransformUpdate : 1;
};
inline RenderSVGViewportContainer* toRenderSVGViewportContainer(RenderObject* object)
diff --git a/Source/WebCore/rendering/svg/SVGRenderSupport.cpp b/Source/WebCore/rendering/svg/SVGRenderSupport.cpp
index 6457ac006..7feb88fec 100644
--- a/Source/WebCore/rendering/svg/SVGRenderSupport.cpp
+++ b/Source/WebCore/rendering/svg/SVGRenderSupport.cpp
@@ -39,6 +39,7 @@
#include "RenderSVGResourceMarker.h"
#include "RenderSVGResourceMasker.h"
#include "RenderSVGRoot.h"
+#include "RenderSVGText.h"
#include "RenderSVGViewportContainer.h"
#include "SVGResources.h"
#include "SVGResourcesCache.h"
@@ -79,6 +80,13 @@ void SVGRenderSupport::mapLocalToContainer(const RenderObject* object, RenderBox
object->parent()->mapLocalToContainer(repaintContainer, false, true, transformState, wasFixed);
}
+static inline bool isRenderingMaskImage(RenderObject* object)
+{
+ if (object->frame() && object->frame()->view())
+ return object->frame()->view()->paintBehavior() & PaintBehaviorRenderingSVGMask;
+ return false;
+}
+
bool SVGRenderSupport::prepareToRenderSVGContent(RenderObject* object, PaintInfo& paintInfo)
{
ASSERT(object);
@@ -89,11 +97,8 @@ bool SVGRenderSupport::prepareToRenderSVGContent(RenderObject* object, PaintInfo
const SVGRenderStyle* svgStyle = style->svgStyle();
ASSERT(svgStyle);
- bool isRenderingMask = false;
- if (object->frame() && object->frame()->view())
- isRenderingMask = object->frame()->view()->paintBehavior() & PaintBehaviorRenderingSVGMask;
-
// Setup transparency layers before setting up SVG resources!
+ bool isRenderingMask = isRenderingMaskImage(object);
float opacity = isRenderingMask ? 1 : style->opacity();
const ShadowData* shadow = svgStyle->shadow();
if (opacity < 1 || shadow) {
@@ -168,7 +173,7 @@ void SVGRenderSupport::finishRenderSVGContent(RenderObject* object, PaintInfo& p
}
#endif
- if (style->opacity() < 1)
+ if (style->opacity() < 1 && !isRenderingMaskImage(object))
paintInfo.context->endTransparencyLayer();
if (svgStyle->shadow())
@@ -245,14 +250,35 @@ static inline bool layoutSizeOfNearestViewportChanged(const RenderObject* start)
return toRenderSVGRoot(start)->isLayoutSizeChanged();
}
+bool SVGRenderSupport::transformToRootChanged(RenderObject* ancestor)
+{
+ while (ancestor && !ancestor->isSVGRoot()) {
+ if (ancestor->isSVGTransformableContainer())
+ return toRenderSVGContainer(ancestor)->didTransformToRootUpdate();
+ if (ancestor->isSVGViewportContainer())
+ return toRenderSVGViewportContainer(ancestor)->didTransformToRootUpdate();
+ ancestor = ancestor->parent();
+ }
+
+ return false;
+}
+
void SVGRenderSupport::layoutChildren(RenderObject* start, bool selfNeedsLayout)
{
bool layoutSizeChanged = layoutSizeOfNearestViewportChanged(start);
+ bool transformChanged = transformToRootChanged(start);
HashSet<RenderObject*> notlayoutedObjects;
for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) {
bool needsLayout = selfNeedsLayout;
+ if (transformChanged) {
+ // If the transform changed we need to update the text metrics (note: this also happens for layoutSizeChanged=true).
+ if (child->isSVGText())
+ toRenderSVGText(child)->setNeedsTextMetricsUpdate();
+ needsLayout = true;
+ }
+
if (layoutSizeChanged) {
// When selfNeedsLayout is false and the layout size changed, we have to check whether this child uses relative lengths
if (SVGElement* element = child->node()->isSVGElement() ? static_cast<SVGElement*>(child->node()) : 0) {
@@ -260,6 +286,8 @@ void SVGRenderSupport::layoutChildren(RenderObject* start, bool selfNeedsLayout)
// When the layout size changed and when using relative values tell the RenderSVGShape to update its shape object
if (child->isSVGShape())
toRenderSVGShape(child)->setNeedsShapeUpdate();
+ else if (child->isSVGText())
+ toRenderSVGText(child)->setNeedsPositioningValuesUpdate();
needsLayout = true;
}
diff --git a/Source/WebCore/rendering/svg/SVGRenderSupport.h b/Source/WebCore/rendering/svg/SVGRenderSupport.h
index f5280ff24..c7b2fdcbf 100644
--- a/Source/WebCore/rendering/svg/SVGRenderSupport.h
+++ b/Source/WebCore/rendering/svg/SVGRenderSupport.h
@@ -72,6 +72,9 @@ public:
// Shared between SVG renderers and resources.
static void applyStrokeStyleToContext(GraphicsContext*, const RenderStyle*, const RenderObject*);
+ // Determines if any ancestor's transform has changed.
+ static bool transformToRootChanged(RenderObject*);
+
// FIXME: These methods do not belong here.
static const RenderSVGRoot* findTreeRootObject(const RenderObject*);
diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp b/Source/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp
index a27f68cd7..02a2123eb 100644
--- a/Source/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp
@@ -79,12 +79,12 @@ void SVGTextLayoutAttributesBuilder::rebuildMetricsForWholeTree(RenderSVGText* t
bool SVGTextLayoutAttributesBuilder::buildLayoutAttributesIfNeeded(RenderSVGText* textRoot)
{
ASSERT(textRoot);
- if (!m_textPositions.isEmpty())
- return m_textLength;
- m_textLength = 0;
- const UChar* lastCharacter = 0;
- collectTextPositioningElements(textRoot, lastCharacter);
+ if (m_textPositions.isEmpty()) {
+ m_textLength = 0;
+ const UChar* lastCharacter = 0;
+ collectTextPositioningElements(textRoot, lastCharacter);
+ }
m_characterDataMap.clear();
if (!m_textLength)