RenderSVGResourceMarker.cpp revision 65f03d4f644ce73618e5f4f50dd694b26f55ae12
1dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block/* 2dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> 365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Copyright (C) 2004, 2005, 2006, 2007, 2008 Rob Buis <buis@kde.org> 4dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. 5dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * 6dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * This library is free software; you can redistribute it and/or 7dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * modify it under the terms of the GNU Library General Public 8dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * License as published by the Free Software Foundation; either 9dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * version 2 of the License, or (at your option) any later version. 10dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * 11dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * This library is distributed in the hope that it will be useful, 12dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * but WITHOUT ANY WARRANTY; without even the implied warranty of 13dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Library General Public License for more details. 15dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * 16dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * You should have received a copy of the GNU Library General Public License 17dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * along with this library; see the file COPYING.LIB. If not, write to 18dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Boston, MA 02110-1301, USA. 20dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block */ 21dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 22dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "config.h" 23db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block 246c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#if ENABLE(SVG) 25dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "RenderSVGResourceMarker.h" 26dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 27dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "GraphicsContext.h" 28dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "RenderSVGContainer.h" 29dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "SVGElement.h" 30dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "SVGMarkerElement.h" 31dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "SVGRenderSupport.h" 32dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "SVGStyledElement.h" 33dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "SVGStyledTransformableElement.h" 34dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 35dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blocknamespace WebCore { 36dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 37dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockRenderSVGResourceType RenderSVGResourceMarker::s_resourceType = MarkerResourceType; 38dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 3921939df44de1705786c545cd1bf519d47250322dBen MurdochRenderSVGResourceMarker::RenderSVGResourceMarker(SVGMarkerElement* node) 4021939df44de1705786c545cd1bf519d47250322dBen Murdoch : RenderSVGResourceContainer(node) 41dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 42dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 43dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 44dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockRenderSVGResourceMarker::~RenderSVGResourceMarker() 45dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 46dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 47dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 48dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid RenderSVGResourceMarker::layout() 49dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 50db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // Invalidate all resources if our layout changed. 51db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block if (m_everHadLayout && selfNeedsLayout()) 52f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick removeAllClientsFromCache(); 53db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block 54dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // RenderSVGHiddenContainer overwrites layout(). We need the 55dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // layouting of RenderSVGContainer for calculating local 56dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // transformations and repaint. 57dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block RenderSVGContainer::layout(); 58dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 59dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 60f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrickvoid RenderSVGResourceMarker::removeAllClientsFromCache(bool markForInvalidation) 61dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 62f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick markAllClientsForInvalidation(markForInvalidation ? LayoutAndBoundariesInvalidation : ParentOnlyInvalidation); 63dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 64dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 65f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrickvoid RenderSVGResourceMarker::removeClientFromCache(RenderObject* client, bool markForInvalidation) 66dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 67db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block ASSERT(client); 68f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick markClientForInvalidation(client, markForInvalidation ? BoundariesInvalidation : ParentOnlyInvalidation); 69dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 70dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 71dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid RenderSVGResourceMarker::applyViewportClip(PaintInfo& paintInfo) 72dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 73ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block if (SVGRenderSupport::isOverflowHidden(this)) 74dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block paintInfo.context->clip(m_viewport); 75dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 76dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 77dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockFloatRect RenderSVGResourceMarker::markerBoundaries(const AffineTransform& markerTransformation) const 78dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 79dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block FloatRect coordinates = RenderSVGContainer::repaintRectInLocalCoordinates(); 80dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 81dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Map repaint rect into parent coordinate space, in which the marker boundaries have to be evaluated 82dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block coordinates = localToParentTransform().mapRect(coordinates); 83dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 84dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return markerTransformation.mapRect(coordinates); 85dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 86dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 87dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockconst AffineTransform& RenderSVGResourceMarker::localToParentTransform() const 88dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 89dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block AffineTransform viewportTranslation(viewportTransform()); 90dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_localToParentTransform = viewportTranslation.translateRight(m_viewport.x(), m_viewport.y()); 91dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return m_localToParentTransform; 92dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // If this class were ever given a localTransform(), then the above would read: 93dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // return viewportTransform() * localTransform() * viewportTranslation; 94dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 95dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 96dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockFloatPoint RenderSVGResourceMarker::referencePoint() const 97dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 98dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(node()); 99dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(marker); 100dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 101dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return FloatPoint(marker->refX().value(marker), marker->refY().value(marker)); 102dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 103dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 104dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockfloat RenderSVGResourceMarker::angle() const 105dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 106dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(node()); 107dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(marker); 108dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 109dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block float angle = -1; 110dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (marker->orientType() == SVGMarkerElement::SVG_MARKER_ORIENT_ANGLE) 111dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block angle = marker->orientAngle().value(); 112dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 113dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return angle; 114dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 115dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 116dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockAffineTransform RenderSVGResourceMarker::markerTransformation(const FloatPoint& origin, float autoAngle, float strokeWidth) const 117dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 118dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(node()); 119dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(marker); 120dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 121dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block float markerAngle = angle(); 122dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block bool useStrokeWidth = (marker->markerUnits() == SVGMarkerElement::SVG_MARKERUNITS_STROKEWIDTH); 123dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 124dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block AffineTransform transform; 125dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block transform.translate(origin.x(), origin.y()); 126dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block transform.rotate(markerAngle == -1 ? autoAngle : markerAngle); 127dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block transform = markerContentTransformation(transform, referencePoint(), useStrokeWidth ? strokeWidth : -1); 128dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return transform; 129dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 130dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 131ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockvoid RenderSVGResourceMarker::draw(PaintInfo& paintInfo, const AffineTransform& transform) 132dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 133ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block PaintInfo info(paintInfo); 134dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block info.context->save(); 135ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block info.applyTransform(transform); 136dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block RenderSVGContainer::paint(info, 0, 0); 137dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block info.context->restore(); 138dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 139dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 140dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockAffineTransform RenderSVGResourceMarker::markerContentTransformation(const AffineTransform& contentTransformation, const FloatPoint& origin, float strokeWidth) const 141dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 142dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // The 'origin' coordinate maps to SVGs refX/refY, given in coordinates relative to the viewport established by the marker 143dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block FloatPoint mappedOrigin = viewportTransform().mapPoint(origin); 144dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 145dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block AffineTransform transformation = contentTransformation; 146dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (strokeWidth != -1) 147dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block transformation.scaleNonUniform(strokeWidth, strokeWidth); 148dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 149dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block transformation.translate(-mappedOrigin.x(), -mappedOrigin.y()); 150dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return transformation; 151dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 152dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 153dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockAffineTransform RenderSVGResourceMarker::viewportTransform() const 154dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 155dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(node()); 156dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(marker); 157dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 158dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return marker->viewBoxToViewTransform(m_viewport.width(), m_viewport.height()); 159dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 160dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 161dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockvoid RenderSVGResourceMarker::calcViewport() 162dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 163dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block if (!selfNeedsLayout()) 164dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return; 165dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 166dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(node()); 167dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(marker); 168dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 169dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block float w = marker->markerWidth().value(marker); 170dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block float h = marker->markerHeight().value(marker); 171dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block m_viewport = FloatRect(0, 0, w, h); 172dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 173dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 174dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block} 1756c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen 1766c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen#endif // ENABLE(SVG) 177