1 /* 2 * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann (at) kde.org> 3 * Copyright (C) 2004, 2005, 2007 Rob Buis <buis (at) kde.org> 4 * Copyright (C) 2007 Eric Seidel <eric (at) webkit.org> 5 * Copyright (C) 2009 Google, Inc. 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Library General Public 9 * License as published by the Free Software Foundation; either 10 * version 2 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Library General Public License for more details. 16 * 17 * You should have received a copy of the GNU Library General Public License 18 * along with this library; see the file COPYING.LIB. If not, write to 19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 * Boston, MA 02110-1301, USA. 21 */ 22 23 #include "config.h" 24 #include "core/rendering/svg/RenderSVGViewportContainer.h" 25 26 #include "core/rendering/PaintInfo.h" 27 #include "core/rendering/svg/SVGRenderSupport.h" 28 #include "core/svg/SVGSVGElement.h" 29 #include "core/svg/SVGUseElement.h" 30 #include "platform/graphics/GraphicsContext.h" 31 32 namespace WebCore { 33 34 RenderSVGViewportContainer::RenderSVGViewportContainer(SVGElement* node) 35 : RenderSVGContainer(node) 36 , m_didTransformToRootUpdate(false) 37 , m_isLayoutSizeChanged(false) 38 , m_needsTransformUpdate(true) 39 { 40 } 41 42 void RenderSVGViewportContainer::determineIfLayoutSizeChanged() 43 { 44 ASSERT(element()); 45 if (!isSVGSVGElement(*element())) 46 return; 47 48 m_isLayoutSizeChanged = toSVGSVGElement(element())->hasRelativeLengths() && selfNeedsLayout(); 49 } 50 51 void RenderSVGViewportContainer::applyViewportClip(PaintInfo& paintInfo) 52 { 53 if (SVGRenderSupport::isOverflowHidden(this)) 54 paintInfo.context->clip(m_viewport); 55 } 56 57 void RenderSVGViewportContainer::calcViewport() 58 { 59 SVGElement* element = this->element(); 60 ASSERT(element); 61 if (!isSVGSVGElement(*element)) 62 return; 63 SVGSVGElement* svg = toSVGSVGElement(element); 64 FloatRect oldViewport = m_viewport; 65 66 SVGLengthContext lengthContext(element); 67 m_viewport = FloatRect(svg->x()->currentValue()->value(lengthContext), svg->y()->currentValue()->value(lengthContext), svg->width()->currentValue()->value(lengthContext), svg->height()->currentValue()->value(lengthContext)); 68 69 if (oldViewport != m_viewport) { 70 setNeedsBoundariesUpdate(); 71 setNeedsTransformUpdate(); 72 } 73 } 74 75 bool RenderSVGViewportContainer::calculateLocalTransform() 76 { 77 m_didTransformToRootUpdate = m_needsTransformUpdate || SVGRenderSupport::transformToRootChanged(parent()); 78 if (!m_needsTransformUpdate) 79 return false; 80 81 m_localToParentTransform = AffineTransform::translation(m_viewport.x(), m_viewport.y()) * viewportTransform(); 82 m_needsTransformUpdate = false; 83 return true; 84 } 85 86 AffineTransform RenderSVGViewportContainer::viewportTransform() const 87 { 88 ASSERT(element()); 89 if (isSVGSVGElement(*element())) { 90 SVGSVGElement* svg = toSVGSVGElement(element()); 91 return svg->viewBoxToViewTransform(m_viewport.width(), m_viewport.height()); 92 } 93 94 return AffineTransform(); 95 } 96 97 bool RenderSVGViewportContainer::pointIsInsideViewportClip(const FloatPoint& pointInParent) 98 { 99 // Respect the viewport clip (which is in parent coords) 100 if (!SVGRenderSupport::isOverflowHidden(this)) 101 return true; 102 103 return m_viewport.contains(pointInParent); 104 } 105 106 void RenderSVGViewportContainer::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset) 107 { 108 ASSERT(element()); 109 // An empty viewBox disables rendering. 110 if (isSVGSVGElement(*element()) && toSVGSVGElement(*element()).hasEmptyViewBox()) 111 return; 112 113 RenderSVGContainer::paint(paintInfo, paintOffset); 114 } 115 116 } 117