Home | History | Annotate | Download | only in rendering
      1 /*
      2     Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann (at) kde.org>
      3                   2004, 2005, 2007 Rob Buis <buis (at) kde.org>
      4                   2007 Eric Seidel <eric (at) webkit.org>
      5                   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     aint 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 
     25 #if ENABLE(SVG)
     26 #include "RenderSVGViewportContainer.h"
     27 
     28 #include "GraphicsContext.h"
     29 
     30 #include "RenderView.h"
     31 #include "SVGMarkerElement.h"
     32 #include "SVGSVGElement.h"
     33 
     34 namespace WebCore {
     35 
     36 RenderSVGViewportContainer::RenderSVGViewportContainer(SVGStyledElement* node)
     37     : RenderSVGContainer(node)
     38 {
     39 }
     40 
     41 FloatRect RenderSVGViewportContainer::markerBoundaries(const AffineTransform& markerTransformation) const
     42 {
     43     FloatRect coordinates = repaintRectInLocalCoordinates();
     44 
     45     // Map repaint rect into parent coordinate space, in which the marker boundaries have to be evaluated
     46     coordinates = localToParentTransform().mapRect(coordinates);
     47 
     48     return markerTransformation.mapRect(coordinates);
     49 }
     50 
     51 AffineTransform RenderSVGViewportContainer::markerContentTransformation(const AffineTransform& contentTransformation, const FloatPoint& origin, float strokeWidth) const
     52 {
     53     // The 'origin' coordinate maps to SVGs refX/refY, given in coordinates relative to the viewport established by the marker
     54     FloatPoint mappedOrigin = viewportTransform().mapPoint(origin);
     55 
     56     AffineTransform transformation = contentTransformation;
     57     if (strokeWidth != -1)
     58         transformation.scaleNonUniform(strokeWidth, strokeWidth);
     59 
     60     transformation.translate(-mappedOrigin.x(), -mappedOrigin.y());
     61     return transformation;
     62 }
     63 
     64 void RenderSVGViewportContainer::applyViewportClip(PaintInfo& paintInfo)
     65 {
     66     if (SVGRenderBase::isOverflowHidden(this))
     67         paintInfo.context->clip(m_viewport);
     68 }
     69 
     70 void RenderSVGViewportContainer::calcViewport()
     71 {
     72     SVGElement* svgelem = static_cast<SVGElement*>(node());
     73     if (svgelem->hasTagName(SVGNames::svgTag)) {
     74         SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
     75 
     76         if (!selfNeedsLayout() && !svg->hasRelativeValues())
     77             return;
     78 
     79         float x = svg->x().value(svg);
     80         float y = svg->y().value(svg);
     81         float w = svg->width().value(svg);
     82         float h = svg->height().value(svg);
     83         m_viewport = FloatRect(x, y, w, h);
     84     } else if (svgelem->hasTagName(SVGNames::markerTag)) {
     85         if (!selfNeedsLayout())
     86             return;
     87 
     88         SVGMarkerElement* svg = static_cast<SVGMarkerElement*>(node());
     89         float w = svg->markerWidth().value(svg);
     90         float h = svg->markerHeight().value(svg);
     91         m_viewport = FloatRect(0, 0, w, h);
     92     }
     93 }
     94 
     95 AffineTransform RenderSVGViewportContainer::viewportTransform() const
     96 {
     97     if (node()->hasTagName(SVGNames::svgTag)) {
     98         SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
     99         return svg->viewBoxToViewTransform(m_viewport.width(), m_viewport.height());
    100     } else if (node()->hasTagName(SVGNames::markerTag)) {
    101         SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(node());
    102         return marker->viewBoxToViewTransform(m_viewport.width(), m_viewport.height());
    103     }
    104 
    105     return AffineTransform();
    106 }
    107 
    108 const AffineTransform& RenderSVGViewportContainer::localToParentTransform() const
    109 {
    110     AffineTransform viewportTranslation(viewportTransform());
    111     m_localToParentTransform = viewportTranslation.translateRight(m_viewport.x(), m_viewport.y());
    112     return m_localToParentTransform;
    113     // If this class were ever given a localTransform(), then the above would read:
    114     // return viewportTransform() * localTransform() * viewportTranslation;
    115 }
    116 
    117 bool RenderSVGViewportContainer::pointIsInsideViewportClip(const FloatPoint& pointInParent)
    118 {
    119     // Respect the viewport clip (which is in parent coords)
    120     if (!SVGRenderBase::isOverflowHidden(this))
    121         return true;
    122 
    123     return m_viewport.contains(pointInParent);
    124 }
    125 
    126 }
    127 
    128 #endif // ENABLE(SVG)
    129