summaryrefslogtreecommitdiff
path: root/src/3rdparty/webkit/WebCore/rendering/RenderReplaced.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/webkit/WebCore/rendering/RenderReplaced.cpp')
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/RenderReplaced.cpp140
1 files changed, 78 insertions, 62 deletions
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderReplaced.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderReplaced.cpp
index 79df0f1b48..e61ac8e780 100644
--- a/src/3rdparty/webkit/WebCore/rendering/RenderReplaced.cpp
+++ b/src/3rdparty/webkit/WebCore/rendering/RenderReplaced.cpp
@@ -28,6 +28,7 @@
#include "RenderLayer.h"
#include "RenderTheme.h"
#include "RenderView.h"
+#include "VisiblePosition.h"
using namespace std;
@@ -42,8 +43,6 @@ const int cDefaultHeight = 150;
RenderReplaced::RenderReplaced(Node* node)
: RenderBox(node)
, m_intrinsicSize(cDefaultWidth, cDefaultHeight)
- , m_selectionState(SelectionNone)
- , m_hasOverflow(false)
{
setReplaced(true);
}
@@ -51,19 +50,17 @@ RenderReplaced::RenderReplaced(Node* node)
RenderReplaced::RenderReplaced(Node* node, const IntSize& intrinsicSize)
: RenderBox(node)
, m_intrinsicSize(intrinsicSize)
- , m_selectionState(SelectionNone)
- , m_hasOverflow(false)
{
setReplaced(true);
}
RenderReplaced::~RenderReplaced()
{
- if (m_hasOverflow)
+ if (replacedHasOverflow())
gOverflowRectMap->remove(this);
}
-void RenderReplaced::styleDidChange(RenderStyle::Diff diff, const RenderStyle* oldStyle)
+void RenderReplaced::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderBox::styleDidChange(diff, oldStyle);
@@ -77,23 +74,16 @@ void RenderReplaced::layout()
{
ASSERT(needsLayout());
- IntRect oldBounds;
- IntRect oldOutlineBox;
- bool checkForRepaint = checkForRepaintDuringLayout();
- if (checkForRepaint) {
- oldBounds = absoluteClippedOverflowRect();
- oldOutlineBox = absoluteOutlineBounds();
- }
+ LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
- m_height = minimumReplacedHeight();
+ setHeight(minimumReplacedHeight());
calcWidth();
calcHeight();
- adjustOverflowForBoxShadow();
-
- if (checkForRepaint)
- repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox);
+ adjustOverflowForBoxShadowAndReflect();
+ repainter.repaintAfterLayout();
+
setNeedsLayout(false);
}
@@ -110,8 +100,8 @@ void RenderReplaced::paint(PaintInfo& paintInfo, int tx, int ty)
if (!shouldPaint(paintInfo, tx, ty))
return;
- tx += m_x;
- ty += m_y;
+ tx += x();
+ ty += y();
if (hasBoxDecorations() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection))
paintBoxDecorations(paintInfo, tx, ty);
@@ -137,8 +127,25 @@ void RenderReplaced::paint(PaintInfo& paintInfo, int tx, int ty)
drawSelectionTint = false;
}
+ bool clipToBorderRadius = style()->overflowX() != OVISIBLE && style()->hasBorderRadius();
+ if (clipToBorderRadius) {
+ // Push a clip if we have a border radius, since we want to round the foreground content that gets painted.
+ paintInfo.context->save();
+
+ IntSize topLeft, topRight, bottomLeft, bottomRight;
+ IntRect borderRect = IntRect(tx, ty, width(), height());
+ style()->getBorderRadiiForRect(borderRect, topLeft, topRight, bottomLeft, bottomRight);
+
+ paintInfo.context->addRoundedRectClip(borderRect, topLeft, topRight, bottomLeft, bottomRight);
+ }
+
paintReplaced(paintInfo, tx, ty);
-
+
+ if (clipToBorderRadius)
+ paintInfo.context->restore();
+
+ // The selection tint never gets clipped by border-radius rounding, since we want it to run right up to the edges of
+ // surrounding content.
if (drawSelectionTint) {
IntRect selectionPaintingRect = localSelectionRect();
selectionPaintingRect.move(tx, ty);
@@ -159,8 +166,8 @@ bool RenderReplaced::shouldPaint(PaintInfo& paintInfo, int& tx, int& ty)
if (style()->visibility() != VISIBLE)
return false;
- int currentTX = tx + m_x;
- int currentTY = ty + m_y;
+ int currentTX = tx + x();
+ int currentTY = ty + y();
// Early exit if the element touches the edges.
int top = currentTY + overflowTop();
@@ -215,11 +222,11 @@ unsigned RenderReplaced::caretMaxRenderedOffset() const
return 1;
}
-VisiblePosition RenderReplaced::positionForCoordinates(int x, int y)
+VisiblePosition RenderReplaced::positionForPoint(const IntPoint& point)
{
InlineBox* box = inlineBoxWrapper();
if (!box)
- return VisiblePosition(element(), 0, DOWNSTREAM);
+ return createVisiblePosition(0, DOWNSTREAM);
// FIXME: This code is buggy if the replaced element is relative positioned.
@@ -228,22 +235,22 @@ VisiblePosition RenderReplaced::positionForCoordinates(int x, int y)
int top = root->topOverflow();
int bottom = root->nextRootBox() ? root->nextRootBox()->topOverflow() : root->bottomOverflow();
- if (y + yPos() < top)
- return VisiblePosition(element(), caretMinOffset(), DOWNSTREAM); // coordinates are above
+ if (point.y() + y() < top)
+ return createVisiblePosition(caretMinOffset(), DOWNSTREAM); // coordinates are above
- if (y + yPos() >= bottom)
- return VisiblePosition(element(), caretMaxOffset(), DOWNSTREAM); // coordinates are below
+ if (point.y() + y() >= bottom)
+ return createVisiblePosition(caretMaxOffset(), DOWNSTREAM); // coordinates are below
- if (element()) {
- if (x <= width() / 2)
- return VisiblePosition(element(), 0, DOWNSTREAM);
- return VisiblePosition(element(), 1, DOWNSTREAM);
+ if (node()) {
+ if (point.x() <= width() / 2)
+ return createVisiblePosition(0, DOWNSTREAM);
+ return createVisiblePosition(1, DOWNSTREAM);
}
- return RenderBox::positionForCoordinates(x, y);
+ return RenderBox::positionForPoint(point);
}
-IntRect RenderReplaced::selectionRect(bool clipToVisibleContent)
+IntRect RenderReplaced::selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent)
{
ASSERT(!needsLayout());
@@ -252,11 +259,9 @@ IntRect RenderReplaced::selectionRect(bool clipToVisibleContent)
IntRect rect = localSelectionRect();
if (clipToVisibleContent)
- computeAbsoluteRepaintRect(rect);
- else {
- FloatPoint absPos = localToAbsoluteForContent(FloatPoint());
- rect.move(absPos.x(), absPos.y());
- }
+ computeRectForRepaint(repaintContainer, rect);
+ else
+ rect = localToContainerQuad(FloatRect(rect), repaintContainer).enclosingBoundingBox();
return rect;
}
@@ -268,19 +273,19 @@ IntRect RenderReplaced::localSelectionRect(bool checkWhetherSelected) const
if (!m_inlineBoxWrapper)
// We're a block-level replaced element. Just return our own dimensions.
- return IntRect(0, 0, width(), height() + borderTopExtra() + borderBottomExtra());
+ return IntRect(0, 0, width(), height());
RenderBlock* cb = containingBlock();
if (!cb)
return IntRect();
RootInlineBox* root = m_inlineBoxWrapper->root();
- return IntRect(0, root->selectionTop() - yPos(), width(), root->selectionHeight());
+ return IntRect(0, root->selectionTop() - y(), width(), root->selectionHeight());
}
void RenderReplaced::setSelectionState(SelectionState s)
{
- m_selectionState = s;
+ RenderBox::setSelectionState(s);
if (m_inlineBoxWrapper) {
RootInlineBox* line = m_inlineBoxWrapper->root();
if (line)
@@ -303,7 +308,7 @@ bool RenderReplaced::isSelected() const
if (s == SelectionStart)
return selectionStart == 0;
- int end = element()->hasChildNodes() ? element()->childNodeCount() : 1;
+ int end = node()->hasChildNodes() ? node()->childNodeCount() : 1;
if (s == SelectionEnd)
return selectionEnd == end;
if (s == SelectionBoth)
@@ -323,31 +328,39 @@ void RenderReplaced::setIntrinsicSize(const IntSize& size)
m_intrinsicSize = size;
}
-void RenderReplaced::adjustOverflowForBoxShadow()
+void RenderReplaced::adjustOverflowForBoxShadowAndReflect()
{
IntRect overflow;
for (ShadowData* boxShadow = style()->boxShadow(); boxShadow; boxShadow = boxShadow->next) {
- IntRect shadow = borderBox();
+ IntRect shadow = borderBoxRect();
shadow.move(boxShadow->x, boxShadow->y);
shadow.inflate(boxShadow->blur);
overflow.unite(shadow);
}
+ // Now that we have an overflow rect including shadow, let's make sure that
+ // the reflection (which can also include the shadow) is also included.
+ if (hasReflection()) {
+ if (overflow.isEmpty())
+ overflow = borderBoxRect();
+ overflow.unite(reflectedRect(overflow));
+ }
+
if (!overflow.isEmpty()) {
if (!gOverflowRectMap)
gOverflowRectMap = new OverflowRectMap();
- overflow.unite(borderBox());
+ overflow.unite(borderBoxRect());
gOverflowRectMap->set(this, overflow);
- m_hasOverflow = true;
- } else if (m_hasOverflow) {
+ setReplacedHasOverflow(true);
+ } else if (replacedHasOverflow()) {
gOverflowRectMap->remove(this);
- m_hasOverflow = false;
+ setReplacedHasOverflow(false);
}
}
int RenderReplaced::overflowHeight(bool) const
{
- if (m_hasOverflow) {
+ if (replacedHasOverflow()) {
IntRect *r = &gOverflowRectMap->find(this)->second;
return r->height() + r->y();
}
@@ -357,7 +370,7 @@ int RenderReplaced::overflowHeight(bool) const
int RenderReplaced::overflowWidth(bool) const
{
- if (m_hasOverflow) {
+ if (replacedHasOverflow()) {
IntRect *r = &gOverflowRectMap->find(this)->second;
return r->width() + r->x();
}
@@ -367,7 +380,7 @@ int RenderReplaced::overflowWidth(bool) const
int RenderReplaced::overflowLeft(bool) const
{
- if (m_hasOverflow)
+ if (replacedHasOverflow())
return gOverflowRectMap->get(this).x();
return 0;
@@ -375,7 +388,7 @@ int RenderReplaced::overflowLeft(bool) const
int RenderReplaced::overflowTop(bool) const
{
- if (m_hasOverflow)
+ if (replacedHasOverflow())
return gOverflowRectMap->get(this).y();
return 0;
@@ -383,24 +396,27 @@ int RenderReplaced::overflowTop(bool) const
IntRect RenderReplaced::overflowRect(bool) const
{
- if (m_hasOverflow)
+ if (replacedHasOverflow())
return gOverflowRectMap->find(this)->second;
- return borderBox();
+ return borderBoxRect();
}
-IntRect RenderReplaced::absoluteClippedOverflowRect()
+IntRect RenderReplaced::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
{
if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent())
return IntRect();
- // The selectionRect can project outside of the overflowRect, so use
- // that for repainting to avoid selection painting glitches
- IntRect r = localSelectionRect(false);
+ // The selectionRect can project outside of the overflowRect, so take their union
+ // for repainting to avoid selection painting glitches.
+ IntRect r = unionRect(localSelectionRect(false), overflowRect(false));
RenderView* v = view();
- if (v)
+ if (v) {
+ // FIXME: layoutDelta needs to be applied in parts before/after transforms and
+ // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308
r.move(v->layoutDelta());
+ }
if (style()) {
if (style()->hasAppearance())
@@ -409,7 +425,7 @@ IntRect RenderReplaced::absoluteClippedOverflowRect()
if (v)
r.inflate(style()->outlineSize());
}
- computeAbsoluteRepaintRect(r);
+ computeRectForRepaint(repaintContainer, r);
return r;
}