Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / rendering / svg / RenderSVGForeignObject.cpp
index 062c5d6..d5e667f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2006 Apple Inc.
  * Copyright (C) 2009 Google, Inc.
  * Copyright (C) Research In Motion Limited 2010. All rights reserved. 
  *
  */
 
 #include "config.h"
-
-#if ENABLE(SVG)
 #include "RenderSVGForeignObject.h"
 
 #include "GraphicsContext.h"
+#include "HitTestResult.h"
 #include "LayoutRepainter.h"
+#include "RenderObject.h"
 #include "RenderSVGResource.h"
 #include "RenderView.h"
 #include "SVGForeignObjectElement.h"
-#include "SVGRenderSupport.h"
+#include "SVGRenderingContext.h"
 #include "SVGResourcesCache.h"
-#include "SVGSVGElement.h"
 #include "TransformState.h"
+#include <wtf/StackStats.h>
 
 namespace WebCore {
 
-RenderSVGForeignObject::RenderSVGForeignObject(SVGForeignObjectElement* node) 
-    : RenderSVGBlock(node)
+RenderSVGForeignObject::RenderSVGForeignObject(SVGForeignObjectElement& element, Ref<RenderStyle>&& style)
+    : RenderSVGBlock(element, WTFMove(style))
     , m_needsTransformUpdate(true)
 {
 }
@@ -46,54 +46,66 @@ RenderSVGForeignObject::~RenderSVGForeignObject()
 {
 }
 
+SVGForeignObjectElement& RenderSVGForeignObject::foreignObjectElement() const
+{
+    return downcast<SVGForeignObjectElement>(RenderSVGBlock::graphicsElement());
+}
+
 void RenderSVGForeignObject::paint(PaintInfo& paintInfo, const LayoutPoint&)
 {
-    if (paintInfo.context->paintingDisabled()
-        || (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection))
+    if (paintInfo.context().paintingDisabled())
+        return;
+
+    if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection)
         return;
 
     PaintInfo childPaintInfo(paintInfo);
-    GraphicsContextStateSaver stateSaver(*childPaintInfo.context);
+    GraphicsContextStateSaver stateSaver(childPaintInfo.context());
     childPaintInfo.applyTransform(localTransform());
 
-    if (SVGRenderSupport::isOverflowHidden(this))
-        childPaintInfo.context->clip(m_viewport);
-
-    bool continueRendering = true;
-    if (paintInfo.phase == PaintPhaseForeground)
-        continueRendering = SVGRenderSupport::prepareToRenderSVGContent(this, childPaintInfo);
-
-    if (continueRendering) {
-        // Paint all phases of FO elements atomically, as though the FO element established its
-        // own stacking context.
-        bool preservePhase = paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip;
-        LayoutPoint childPoint = IntPoint();
-        childPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
-        RenderBlock::paint(childPaintInfo, IntPoint());
-        if (!preservePhase) {
-            childPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
-            RenderBlock::paint(childPaintInfo, childPoint);
-            childPaintInfo.phase = PaintPhaseFloat;
-            RenderBlock::paint(childPaintInfo, childPoint);
-            childPaintInfo.phase = PaintPhaseForeground;
-            RenderBlock::paint(childPaintInfo, childPoint);
-            childPaintInfo.phase = PaintPhaseOutline;
-            RenderBlock::paint(childPaintInfo, childPoint);
-        }
+    if (SVGRenderSupport::isOverflowHidden(*this))
+        childPaintInfo.context().clip(m_viewport);
+
+    SVGRenderingContext renderingContext;
+    if (paintInfo.phase == PaintPhaseForeground) {
+        renderingContext.prepareToRenderSVGContent(*this, childPaintInfo);
+        if (!renderingContext.isRenderingPrepared())
+            return;
     }
 
-    if (paintInfo.phase == PaintPhaseForeground)
-        SVGRenderSupport::finishRenderSVGContent(this, childPaintInfo, paintInfo.context);
+    LayoutPoint childPoint = IntPoint();
+    if (paintInfo.phase == PaintPhaseSelection) {
+        RenderBlock::paint(childPaintInfo, childPoint);
+        return;
+    }
+
+    // Paint all phases of FO elements atomically, as though the FO element established its
+    // own stacking context.
+    childPaintInfo.phase = PaintPhaseBlockBackground;
+    RenderBlock::paint(childPaintInfo, childPoint);
+    childPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
+    RenderBlock::paint(childPaintInfo, childPoint);
+    childPaintInfo.phase = PaintPhaseFloat;
+    RenderBlock::paint(childPaintInfo, childPoint);
+    childPaintInfo.phase = PaintPhaseForeground;
+    RenderBlock::paint(childPaintInfo, childPoint);
+    childPaintInfo.phase = PaintPhaseOutline;
+    RenderBlock::paint(childPaintInfo, childPoint);
+}
+
+LayoutRect RenderSVGForeignObject::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const
+{
+    return SVGRenderSupport::clippedOverflowRectForRepaint(*this, repaintContainer);
 }
 
-LayoutRect RenderSVGForeignObject::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const
+FloatRect RenderSVGForeignObject::computeFloatRectForRepaint(const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed) const
 {
-    return SVGRenderSupport::clippedOverflowRectForRepaint(this, repaintContainer);
+    return SVGRenderSupport::computeFloatRectForRepaint(*this, repaintRect, repaintContainer, fixed);
 }
 
-void RenderSVGForeignObject::computeRectForRepaint(RenderBoxModelObject* repaintContainer, LayoutRect& repaintRect, bool fixed) const
+LayoutRect RenderSVGForeignObject::computeRectForRepaint(const LayoutRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed) const
 {
-    SVGRenderSupport::computeRectForRepaint(this, repaintContainer, repaintRect, fixed);
+    return enclosingLayoutRect(computeFloatRectForRepaint(repaintRect, repaintContainer, fixed));
 }
 
 const AffineTransform& RenderSVGForeignObject::localToParentTransform() const
@@ -103,31 +115,33 @@ const AffineTransform& RenderSVGForeignObject::localToParentTransform() const
     return m_localToParentTransform;
 }
 
-void RenderSVGForeignObject::computeLogicalWidth()
+void RenderSVGForeignObject::updateLogicalWidth()
 {
     // FIXME: Investigate in size rounding issues
     // FIXME: Remove unnecessary rounding when layout is off ints: webkit.org/b/63656
     setWidth(static_cast<int>(roundf(m_viewport.width())));
 }
 
-void RenderSVGForeignObject::computeLogicalHeight()
+void RenderSVGForeignObject::computeLogicalHeight(LayoutUnit, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const
 {
     // FIXME: Investigate in size rounding issues
     // FIXME: Remove unnecessary rounding when layout is off ints: webkit.org/b/63656
-    setHeight(static_cast<int>(roundf(m_viewport.height())));
+    // FIXME: Is this correct for vertical writing mode?
+    computedValues.m_extent = static_cast<int>(roundf(m_viewport.height()));
+    computedValues.m_position = logicalTop;
 }
 
 void RenderSVGForeignObject::layout()
 {
+    StackStats::LayoutCheckPoint layoutCheckPoint;
     ASSERT(needsLayout());
-    ASSERT(!view()->layoutStateEnabled()); // RenderSVGRoot disables layoutState for the SVG rendering tree.
+    ASSERT(!view().layoutStateEnabled()); // RenderSVGRoot disables layoutState for the SVG rendering tree.
 
-    LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
-    SVGForeignObjectElement* foreign = static_cast<SVGForeignObjectElement*>(node());
+    LayoutRepainter repainter(*this, SVGRenderSupport::checkForSVGRepaintDuringLayout(*this));
 
     bool updateCachedBoundariesInParents = false;
     if (m_needsTransformUpdate) {
-        m_localTransform = foreign->animatedLocalTransform();
+        m_localTransform = foreignObjectElement().animatedLocalTransform();
         m_needsTransformUpdate = false;
         updateCachedBoundariesInParents = true;
     }
@@ -135,9 +149,9 @@ void RenderSVGForeignObject::layout()
     FloatRect oldViewport = m_viewport;
 
     // Cache viewport boundaries
-    SVGLengthContext lengthContext(foreign);
-    FloatPoint viewportLocation(foreign->x().value(lengthContext), foreign->y().value(lengthContext));
-    m_viewport = FloatRect(viewportLocation, FloatSize(foreign->width().value(lengthContext), foreign->height().value(lengthContext)));
+    SVGLengthContext lengthContext(&foreignObjectElement());
+    FloatPoint viewportLocation(foreignObjectElement().x().value(lengthContext), foreignObjectElement().y().value(lengthContext));
+    m_viewport = FloatRect(viewportLocation, FloatSize(foreignObjectElement().width().value(lengthContext), foreignObjectElement().height().value(lengthContext)));
     if (!updateCachedBoundariesInParents)
         updateCachedBoundariesInParents = oldViewport != m_viewport;
 
@@ -148,7 +162,7 @@ void RenderSVGForeignObject::layout()
     // FIXME: Investigate in location rounding issues - only affects RenderSVGForeignObject & RenderSVGText
     setLocation(roundedIntPoint(viewportLocation));
 
-    bool layoutChanged = m_everHadLayout && selfNeedsLayout();
+    bool layoutChanged = everHadLayout() && selfNeedsLayout();
     RenderBlock::layout();
     ASSERT(!needsLayout());
 
@@ -158,33 +172,44 @@ void RenderSVGForeignObject::layout()
 
     // Invalidate all resources of this client if our layout changed.
     if (layoutChanged)
-        SVGResourcesCache::clientLayoutChanged(this);
+        SVGResourcesCache::clientLayoutChanged(*this);
 
     repainter.repaintAfterLayout();
 }
 
 bool RenderSVGForeignObject::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
 {
-    FloatPoint localPoint = localTransform().inverse().mapPoint(pointInParent);
+    // Embedded content is drawn in the foreground phase.
+    if (hitTestAction != HitTestForeground)
+        return false;
+
+    FloatPoint localPoint = localTransform().inverse().valueOr(AffineTransform()).mapPoint(pointInParent);
 
     // Early exit if local point is not contained in clipped viewport area
-    if (SVGRenderSupport::isOverflowHidden(this) && !m_viewport.contains(localPoint))
+    if (SVGRenderSupport::isOverflowHidden(*this) && !m_viewport.contains(localPoint))
         return false;
 
-    return RenderBlock::nodeAtPoint(request, result, roundedLayoutPoint(localPoint), LayoutPoint(), hitTestAction);
+    // FOs establish a stacking context, so we need to hit-test all layers.
+    HitTestLocation hitTestLocation(localPoint);
+    return RenderBlock::nodeAtPoint(request, result, hitTestLocation, LayoutPoint(), HitTestForeground)
+        || RenderBlock::nodeAtPoint(request, result, hitTestLocation, LayoutPoint(), HitTestFloat)
+        || RenderBlock::nodeAtPoint(request, result, hitTestLocation, LayoutPoint(), HitTestChildBlockBackgrounds);
 }
 
-bool RenderSVGForeignObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, const LayoutPoint&, const LayoutPoint&, HitTestAction)
+bool RenderSVGForeignObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation&, const LayoutPoint&, HitTestAction)
 {
     ASSERT_NOT_REACHED();
     return false;
 }
 
-void RenderSVGForeignObject::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool /* fixed */, bool /* useTransforms */, TransformState& transformState, bool* wasFixed) const
+void RenderSVGForeignObject::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed) const
 {
-    SVGRenderSupport::mapLocalToContainer(this, repaintContainer, transformState, wasFixed);
+    SVGRenderSupport::mapLocalToContainer(*this, repaintContainer, transformState, wasFixed);
 }
 
+const RenderObject* RenderSVGForeignObject::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
+{
+    return SVGRenderSupport::pushMappingToContainer(*this, ancestorToStopAt, geometryMap);
 }
 
-#endif
+}