summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/rendering/RenderLayer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/rendering/RenderLayer.cpp')
-rw-r--r--Source/WebCore/rendering/RenderLayer.cpp154
1 files changed, 108 insertions, 46 deletions
diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp
index 29a6fc9..e278c75 100644
--- a/Source/WebCore/rendering/RenderLayer.cpp
+++ b/Source/WebCore/rendering/RenderLayer.cpp
@@ -188,6 +188,8 @@ RenderLayer::RenderLayer(RenderBoxModelObject* renderer)
, m_scrollCorner(0)
, m_resizer(0)
{
+ ScrollableArea::setConstrainsScrollingToContentEdge(false);
+
if (!renderer->firstChild() && renderer->style()) {
m_visibleContentStatusDirty = false;
m_hasVisibleContent = renderer->style()->visibility() == VISIBLE;
@@ -960,7 +962,7 @@ static IntRect transparencyClipBox(const RenderLayer* l, const RenderLayer* root
TransformationMatrix transform;
transform.translate(x, y);
- transform = *l->transform() * transform;
+ transform = transform * *l->transform();
IntRect clipRect = l->boundingBox(l);
expandClipRectForDescendantsAndReflection(clipRect, l, l, paintBehavior);
@@ -1532,7 +1534,7 @@ IntRect RenderLayer::getRectToExpose(const IntRect &visibleRect, const IntRect &
scrollX = ScrollAlignment::getHiddenBehavior(alignX);
// If we're trying to align to the closest edge, and the exposeRect is further right
// than the visibleRect, and not bigger than the visible area, then align with the right.
- if (scrollX == alignToClosestEdge && exposeRect.right() > visibleRect.right() && exposeRect.width() < visibleRect.width())
+ if (scrollX == alignToClosestEdge && exposeRect.maxX() > visibleRect.maxX() && exposeRect.width() < visibleRect.width())
scrollX = alignRight;
// Given the X behavior, compute the X coordinate.
@@ -1540,7 +1542,7 @@ IntRect RenderLayer::getRectToExpose(const IntRect &visibleRect, const IntRect &
if (scrollX == noScroll)
x = visibleRect.x();
else if (scrollX == alignRight)
- x = exposeRect.right() - visibleRect.width();
+ x = exposeRect.maxX() - visibleRect.width();
else if (scrollX == alignCenter)
x = exposeRect.x() + (exposeRect.width() - visibleRect.width()) / 2;
else
@@ -1565,7 +1567,7 @@ IntRect RenderLayer::getRectToExpose(const IntRect &visibleRect, const IntRect &
scrollY = ScrollAlignment::getHiddenBehavior(alignY);
// If we're trying to align to the closest edge, and the exposeRect is further down
// than the visibleRect, and not bigger than the visible area, then align with the bottom.
- if (scrollY == alignToClosestEdge && exposeRect.bottom() > visibleRect.bottom() && exposeRect.height() < visibleRect.height())
+ if (scrollY == alignToClosestEdge && exposeRect.maxY() > visibleRect.maxY() && exposeRect.height() < visibleRect.height())
scrollY = alignBottom;
// Given the Y behavior, compute the Y coordinate.
@@ -1573,7 +1575,7 @@ IntRect RenderLayer::getRectToExpose(const IntRect &visibleRect, const IntRect &
if (scrollY == noScroll)
y = visibleRect.y();
else if (scrollY == alignBottom)
- y = exposeRect.bottom() - visibleRect.height();
+ y = exposeRect.maxY() - visibleRect.height();
else if (scrollY == alignCenter)
y = exposeRect.y() + (exposeRect.height() - visibleRect.height()) / 2;
else
@@ -1681,7 +1683,7 @@ int RenderLayer::scrollPosition(Scrollbar* scrollbar) const
if (scrollbar->orientation() == HorizontalScrollbar)
return scrollXOffset();
if (scrollbar->orientation() == VerticalScrollbar)
- return m_scrollY;
+ return scrollYOffset();
return 0;
}
@@ -1710,8 +1712,8 @@ static IntRect cornerRect(const RenderLayer* layer, const IntRect& bounds)
horizontalThickness = layer->verticalScrollbar()->width();
verticalThickness = layer->horizontalScrollbar()->height();
}
- return IntRect(bounds.right() - horizontalThickness - layer->renderer()->style()->borderRightWidth(),
- bounds.bottom() - verticalThickness - layer->renderer()->style()->borderBottomWidth(),
+ return IntRect(bounds.maxX() - horizontalThickness - layer->renderer()->style()->borderRightWidth(),
+ bounds.maxY() - verticalThickness - layer->renderer()->style()->borderBottomWidth(),
horizontalThickness, verticalThickness);
}
@@ -1789,6 +1791,21 @@ IntPoint RenderLayer::convertFromContainingViewToScrollbar(const Scrollbar* scro
return point;
}
+IntSize RenderLayer::contentsSize() const
+{
+ return IntSize(const_cast<RenderLayer*>(this)->scrollWidth(), const_cast<RenderLayer*>(this)->scrollHeight());
+}
+
+int RenderLayer::visibleHeight() const
+{
+ return m_height;
+}
+
+int RenderLayer::visibleWidth() const
+{
+ return m_width;
+}
+
IntSize RenderLayer::scrollbarOffset(const Scrollbar* scrollbar) const
{
RenderBox* box = renderBox();
@@ -1846,10 +1863,13 @@ void RenderLayer::setHasHorizontalScrollbar(bool hasScrollbar)
if (hasScrollbar == (m_hBar != 0))
return;
- if (hasScrollbar)
+ if (hasScrollbar) {
m_hBar = createScrollbar(HorizontalScrollbar);
- else
+ ScrollableArea::didAddHorizontalScrollbar(m_hBar.get());
+ } else {
+ ScrollableArea::willRemoveHorizontalScrollbar(m_hBar.get());
destroyScrollbar(HorizontalScrollbar);
+ }
// Destroying or creating one bar can cause our scrollbar corner to come and go. We need to update the opposite scrollbar's style.
if (m_hBar)
@@ -1869,10 +1889,13 @@ void RenderLayer::setHasVerticalScrollbar(bool hasScrollbar)
if (hasScrollbar == (m_vBar != 0))
return;
- if (hasScrollbar)
+ if (hasScrollbar) {
m_vBar = createScrollbar(VerticalScrollbar);
- else
+ ScrollableArea::didAddVerticalScrollbar(m_vBar.get());
+ } else {
+ ScrollableArea::willRemoveVerticalScrollbar(m_vBar.get());
destroyScrollbar(VerticalScrollbar);
+ }
// Destroying or creating one bar can cause our scrollbar corner to come and go. We need to update the opposite scrollbar's style.
if (m_hBar)
@@ -1936,14 +1959,14 @@ void RenderLayer::positionOverflowControls(int tx, int ty)
IntRect scrollCorner(scrollCornerRect(this, borderBox));
IntRect absBounds(borderBox.x() + tx, borderBox.y() + ty, borderBox.width(), borderBox.height());
if (m_vBar)
- m_vBar->setFrameRect(IntRect(absBounds.right() - box->borderRight() - m_vBar->width(),
+ m_vBar->setFrameRect(IntRect(absBounds.maxX() - box->borderRight() - m_vBar->width(),
absBounds.y() + box->borderTop(),
m_vBar->width(),
absBounds.height() - (box->borderTop() + box->borderBottom()) - scrollCorner.height()));
if (m_hBar)
m_hBar->setFrameRect(IntRect(absBounds.x() + box->borderLeft(),
- absBounds.bottom() - box->borderBottom() - m_hBar->height(),
+ absBounds.maxY() - box->borderBottom() - m_hBar->height(),
absBounds.width() - (box->borderLeft() + box->borderRight()) - scrollCorner.width(),
m_hBar->height()));
@@ -2000,7 +2023,7 @@ int RenderLayer::overflowBottom() const
RenderBox* box = renderBox();
IntRect overflowRect(box->layoutOverflowRect());
box->flipForWritingMode(overflowRect);
- return overflowRect.bottom();
+ return overflowRect.maxY();
}
int RenderLayer::overflowLeft() const
@@ -2016,7 +2039,7 @@ int RenderLayer::overflowRight() const
RenderBox* box = renderBox();
IntRect overflowRect(box->layoutOverflowRect());
box->flipForWritingMode(overflowRect);
- return overflowRect.right();
+ return overflowRect.maxX();
}
void RenderLayer::computeScrollDimensions(bool* needHBar, bool* needVBar)
@@ -2078,8 +2101,8 @@ void RenderLayer::updateScrollInfoAfterLayout()
// Layout may cause us to be in an invalid scroll position. In this case we need
// to pull our scroll offsets back to the max (or push them up to the min).
int newX = max(0, min(scrollXOffset(), scrollWidth() - box->clientWidth()));
- int newY = max(0, min(m_scrollY, scrollHeight() - box->clientHeight()));
- if (newX != scrollXOffset() || newY != m_scrollY) {
+ int newY = max(0, min(scrollYOffset(), scrollHeight() - box->clientHeight()));
+ if (newX != scrollXOffset() || newY != scrollYOffset()) {
RenderView* view = renderer()->view();
ASSERT(view);
// scrollToOffset() may call updateLayerPositions(), which doesn't work
@@ -2163,7 +2186,10 @@ void RenderLayer::updateScrollInfoAfterLayout()
m_vBar->setProportion(clientHeight, m_scrollHeight);
}
+ RenderView* view = renderer()->view();
+ view->disableLayoutState();
scrollToOffset(scrollXOffset(), scrollYOffset());
+ view->enableLayoutState();
if (renderer()->node() && renderer()->document()->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
updateOverflowStatus(horizontalOverflow, verticalOverflow);
@@ -2256,7 +2282,7 @@ void RenderLayer::paintResizer(GraphicsContext* context, int tx, int ty, const I
// Paint the resizer control.
DEFINE_STATIC_LOCAL(RefPtr<Image>, resizeCornerImage, (Image::loadPlatformResource("textAreaResizeCorner")));
- IntPoint imagePoint(absRect.right() - resizeCornerImage->width(), absRect.bottom() - resizeCornerImage->height());
+ IntPoint imagePoint(absRect.maxX() - resizeCornerImage->width(), absRect.maxY() - resizeCornerImage->height());
context->drawImage(resizeCornerImage.get(), box->style()->colorSpace(), imagePoint);
// Draw a frame around the resizer (1px grey line) if there are any scrollbars present.
@@ -2634,13 +2660,18 @@ void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, RenderLaye
int layerY = 0;
columnBlock->layer()->convertToLayerCoords(rootLayer, layerX, layerY);
+ bool isHorizontal = columnBlock->style()->isHorizontalWritingMode();
+
ColumnInfo* colInfo = columnBlock->columnInfo();
unsigned colCount = columnBlock->columnCount(colInfo);
- int currYOffset = 0;
+ int currLogicalTopOffset = 0;
for (unsigned i = 0; i < colCount; i++) {
// For each rect, we clip to the rect, and then we adjust our coords.
IntRect colRect = columnBlock->columnRectAt(colInfo, i);
- int currXOffset = colRect.x() - (columnBlock->borderLeft() + columnBlock->paddingLeft());
+ columnBlock->flipForWritingMode(colRect);
+ int logicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - columnBlock->logicalLeftOffsetForContent();
+ IntSize offset = isHorizontal ? IntSize(logicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, logicalLeftOffset);
+
colRect.move(layerX, layerY);
IntRect localDirtyRect(paintDirtyRect);
@@ -2660,7 +2691,7 @@ void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, RenderLaye
if (oldHasTransform)
oldTransform = *childLayer->transform();
TransformationMatrix newTransform(oldTransform);
- newTransform.translateRight(currXOffset, currYOffset);
+ newTransform.translateRight(offset.width(), offset.height());
childLayer->m_transform.set(new TransformationMatrix(newTransform));
childLayer->paintLayer(rootLayer, context, localDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, paintFlags);
@@ -2675,7 +2706,7 @@ void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, RenderLaye
int childY = 0;
columnLayers[colIndex - 1]->convertToLayerCoords(rootLayer, childX, childY);
TransformationMatrix transform;
- transform.translateRight(childX + currXOffset, childY + currYOffset);
+ transform.translateRight(childX + offset.width(), childY + offset.height());
// Apply the transform.
context->concatCTM(transform.toAffineTransform());
@@ -2690,7 +2721,11 @@ void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, RenderLaye
}
// Move to the next position.
- currYOffset -= colRect.height();
+ int blockDelta = isHorizontal ? colRect.height() : colRect.width();
+ if (columnBlock->style()->isFlippedBlocksWritingMode())
+ currLogicalTopOffset += blockDelta;
+ else
+ currLogicalTopOffset -= blockDelta;
}
}
@@ -3111,21 +3146,35 @@ RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, Rend
int colCount = columnBlock->columnCount(colInfo);
// We have to go backwards from the last column to the first.
- int left = columnBlock->borderLeft() + columnBlock->paddingLeft();
- int currYOffset = 0;
+ bool isHorizontal = columnBlock->style()->isHorizontalWritingMode();
+ int logicalLeft = columnBlock->logicalLeftOffsetForContent();
+ int currLogicalTopOffset = 0;
int i;
- for (i = 0; i < colCount; i++)
- currYOffset -= columnBlock->columnRectAt(colInfo, i).height();
+ for (i = 0; i < colCount; i++) {
+ IntRect colRect = columnBlock->columnRectAt(colInfo, i);
+ int blockDelta = (isHorizontal ? colRect.height() : colRect.width());
+ if (columnBlock->style()->isFlippedBlocksWritingMode())
+ currLogicalTopOffset += blockDelta;
+ else
+ currLogicalTopOffset -= blockDelta;
+ }
for (i = colCount - 1; i >= 0; i--) {
// For each rect, we clip to the rect, and then we adjust our coords.
IntRect colRect = columnBlock->columnRectAt(colInfo, i);
- int currXOffset = colRect.x() - left;
- currYOffset += colRect.height();
+ columnBlock->flipForWritingMode(colRect);
+ int currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft;
+ int blockDelta = (isHorizontal ? colRect.height() : colRect.width());
+ if (columnBlock->style()->isFlippedBlocksWritingMode())
+ currLogicalTopOffset -= blockDelta;
+ else
+ currLogicalTopOffset += blockDelta;
colRect.move(layerX, layerY);
IntRect localClipRect(hitTestRect);
localClipRect.intersect(colRect);
+ IntSize offset = isHorizontal ? IntSize(currLogicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, currLogicalLeftOffset);
+
if (!localClipRect.isEmpty() && localClipRect.intersects(result.rectForPoint(hitTestPoint))) {
RenderLayer* hitLayer = 0;
if (!columnIndex) {
@@ -3135,7 +3184,7 @@ RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, Rend
if (oldHasTransform)
oldTransform = *childLayer->transform();
TransformationMatrix newTransform(oldTransform);
- newTransform.translateRight(currXOffset, currYOffset);
+ newTransform.translateRight(offset.width(), offset.height());
childLayer->m_transform.set(new TransformationMatrix(newTransform));
hitLayer = childLayer->hitTestLayer(rootLayer, columnLayers[0], request, result, localClipRect, hitTestPoint, false, transformState, zOffset);
@@ -3148,7 +3197,7 @@ RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, Rend
// This involves subtracting out the position of the layer in our current coordinate space.
RenderLayer* nextLayer = columnLayers[columnIndex - 1];
RefPtr<HitTestingTransformState> newTransformState = nextLayer->createLocalTransformState(rootLayer, nextLayer, localClipRect, hitTestPoint, transformState);
- newTransformState->translate(currXOffset, currYOffset, HitTestingTransformState::AccumulateTransform);
+ newTransformState->translate(offset.width(), offset.height(), HitTestingTransformState::AccumulateTransform);
IntPoint localPoint = roundedIntPoint(newTransformState->mappedPoint());
IntRect localHitTestRect = newTransformState->mappedQuad().enclosingBoundingBox();
newTransformState->flatten();
@@ -3437,19 +3486,9 @@ IntRect RenderLayer::localBoundingBox() const
// as part of our bounding box. We do this because we are the responsible layer for both hit testing and painting those
// floats.
IntRect result;
- if (renderer()->isRenderInline()) {
- // Go from our first line box to our last line box.
- RenderInline* inlineFlow = toRenderInline(renderer());
- InlineFlowBox* firstBox = inlineFlow->firstLineBox();
- if (!firstBox)
- return result;
- int top = firstBox->topVisualOverflow();
- int bottom = inlineFlow->lastLineBox()->bottomVisualOverflow();
- int left = firstBox->x();
- for (InlineFlowBox* curr = firstBox->nextLineBox(); curr; curr = curr->nextLineBox())
- left = min(left, curr->x());
- result = IntRect(left, top, width(), bottom - top);
- } else if (renderer()->isTableRow()) {
+ if (renderer()->isRenderInline())
+ result = toRenderInline(renderer())->linesVisualOverflowBoundingBox();
+ else if (renderer()->isTableRow()) {
// Our bounding box is just the union of all of our cells' border/overflow rects.
for (RenderObject* child = renderer()->firstChild(); child; child = child->nextSibling()) {
if (child->isTableCell()) {
@@ -3485,7 +3524,10 @@ IntRect RenderLayer::localBoundingBox() const
IntRect RenderLayer::boundingBox(const RenderLayer* ancestorLayer) const
{
IntRect result = localBoundingBox();
-
+ if (renderer()->isBox())
+ renderBox()->flipForWritingMode(result);
+ else
+ renderer()->containingBlock()->flipForWritingMode(result);
int deltaX = 0, deltaY = 0;
convertToLayerCoords(ancestorLayer, deltaX, deltaY);
result.move(deltaX, deltaY);
@@ -3538,6 +3580,26 @@ bool RenderLayer::hasCompositedMask() const
}
#endif
+bool RenderLayer::scrollbarWillRenderIntoCompositingLayer() const
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (enclosingCompositingLayer())
+ return true;
+
+ RenderView* view = renderer()->view();
+ if (!view)
+ return false;
+
+ FrameView* frameView = view->frameView();
+ if (!frameView)
+ return false;
+
+ return frameView->isEnclosedInCompositingLayer();
+#else
+ return false;
+#endif
+}
+
bool RenderLayer::paintsWithTransform(PaintBehavior paintBehavior) const
{
#if USE(ACCELERATED_COMPOSITING)