2 * Copyright (C) 2006 Apple Computer, Inc.
3 * Copyright (C) 2009 Google, Inc.
4 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
25 #include "RenderSVGForeignObject.h"
27 #include "GraphicsContext.h"
28 #include "LayoutRepainter.h"
29 #include "RenderSVGResource.h"
30 #include "RenderView.h"
31 #include "SVGForeignObjectElement.h"
32 #include "SVGRenderSupport.h"
33 #include "SVGSVGElement.h"
34 #include "TransformState.h"
38 RenderSVGForeignObject::RenderSVGForeignObject(SVGForeignObjectElement* node)
39 : RenderSVGBlock(node)
40 , m_needsTransformUpdate(true)
44 RenderSVGForeignObject::~RenderSVGForeignObject()
48 void RenderSVGForeignObject::paint(PaintInfo& paintInfo, const LayoutPoint&)
50 if (paintInfo.context->paintingDisabled())
53 PaintInfo childPaintInfo(paintInfo);
54 GraphicsContextStateSaver stateSaver(*childPaintInfo.context);
55 childPaintInfo.applyTransform(localTransform());
57 if (SVGRenderSupport::isOverflowHidden(this))
58 childPaintInfo.context->clip(m_viewport);
60 float opacity = style()->opacity();
62 childPaintInfo.context->beginTransparencyLayer(opacity);
64 RenderBlock::paint(childPaintInfo, IntPoint());
67 childPaintInfo.context->endTransparencyLayer();
70 LayoutRect RenderSVGForeignObject::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer) const
72 return SVGRenderSupport::clippedOverflowRectForRepaint(this, repaintContainer);
75 void RenderSVGForeignObject::computeRectForRepaint(RenderBoxModelObject* repaintContainer, LayoutRect& repaintRect, bool fixed) const
77 SVGRenderSupport::computeRectForRepaint(this, repaintContainer, repaintRect, fixed);
80 const AffineTransform& RenderSVGForeignObject::localToParentTransform() const
82 m_localToParentTransform = localTransform();
83 m_localToParentTransform.translate(m_viewport.x(), m_viewport.y());
84 return m_localToParentTransform;
87 void RenderSVGForeignObject::computeLogicalWidth()
89 // FIXME: Investigate in size rounding issues
90 // FIXME: Remove unnecessary rounding when layout is off ints: webkit.org/b/63656
91 setWidth(static_cast<int>(roundf(m_viewport.width())));
94 void RenderSVGForeignObject::computeLogicalHeight()
96 // FIXME: Investigate in size rounding issues
97 // FIXME: Remove unnecessary rounding when layout is off ints: webkit.org/b/63656
98 setHeight(static_cast<int>(roundf(m_viewport.height())));
101 void RenderSVGForeignObject::layout()
103 ASSERT(needsLayout());
104 ASSERT(!view()->layoutStateEnabled()); // RenderSVGRoot disables layoutState for the SVG rendering tree.
106 LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
107 SVGForeignObjectElement* foreign = static_cast<SVGForeignObjectElement*>(node());
109 bool updateCachedBoundariesInParents = false;
110 if (m_needsTransformUpdate) {
111 m_localTransform = foreign->animatedLocalTransform();
112 m_needsTransformUpdate = false;
113 updateCachedBoundariesInParents = true;
116 FloatRect oldViewport = m_viewport;
118 // Cache viewport boundaries
119 FloatPoint viewportLocation(foreign->x().value(foreign), foreign->y().value(foreign));
120 m_viewport = FloatRect(viewportLocation, FloatSize(foreign->width().value(foreign), foreign->height().value(foreign)));
121 if (!updateCachedBoundariesInParents)
122 updateCachedBoundariesInParents = oldViewport != m_viewport;
124 // Set box origin to the foreignObject x/y translation, so positioned objects in XHTML content get correct
125 // positions. A regular RenderBoxModelObject would pull this information from RenderStyle - in SVG those
126 // properties are ignored for non <svg> elements, so we mimic what happens when specifying them through CSS.
128 // FIXME: Investigate in location rounding issues - only affects RenderSVGForeignObject & RenderSVGText
129 setLocation(roundedIntPoint(viewportLocation));
131 bool layoutChanged = m_everHadLayout && selfNeedsLayout();
132 RenderBlock::layout();
133 ASSERT(!needsLayout());
135 // If our bounds changed, notify the parents.
136 if (updateCachedBoundariesInParents)
137 RenderSVGBlock::setNeedsBoundariesUpdate();
139 // Invalidate all resources of this client if our layout changed.
141 SVGResourcesCache::clientLayoutChanged(this);
143 repainter.repaintAfterLayout();
146 bool RenderSVGForeignObject::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
148 FloatPoint localPoint = localTransform().inverse().mapPoint(pointInParent);
150 // Early exit if local point is not contained in clipped viewport area
151 if (SVGRenderSupport::isOverflowHidden(this) && !m_viewport.contains(localPoint))
154 return RenderBlock::nodeAtPoint(request, result, roundedLayoutPoint(localPoint), LayoutPoint(), hitTestAction);
157 bool RenderSVGForeignObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, const LayoutPoint&, const LayoutPoint&, HitTestAction)
159 ASSERT_NOT_REACHED();
163 void RenderSVGForeignObject::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState, bool* wasFixed) const
165 // When crawling up the hierachy starting from foreignObject child content, useTransforms may not be set to true.
167 useTransforms = true;
168 SVGRenderSupport::mapLocalToContainer(this, repaintContainer, fixed, useTransforms, transformState, wasFixed);