/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Mozilla SVG project. * * The Initial Developer of the Original Code is * Crocodile Clips Ltd.. * Portions created by the Initial Developer are Copyright (C) 2001 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Alex Fritze <alex.fritze@crocodile-clips.com> (original author) * Jonathan Watt <jonathan.watt@strath.ac.uk> * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */#include"mozilla/Util.h"#include"nsSVGGraphicElement.h"#include"nsSVGSVGElement.h"#include"DOMSVGAnimatedTransformList.h"#include"DOMSVGMatrix.h"#include"nsGkAtoms.h"#include"nsIDOMEventTarget.h"#include"nsIFrame.h"#include"nsISVGChildFrame.h"#include"nsIDOMSVGPoint.h"#include"nsSVGUtils.h"#include"nsDOMError.h"#include"nsSVGRect.h"#include"nsContentUtils.h"usingnamespacemozilla;//----------------------------------------------------------------------// nsISupports methodsNS_IMPL_ADDREF_INHERITED(nsSVGGraphicElement,nsSVGGraphicElementBase)NS_IMPL_RELEASE_INHERITED(nsSVGGraphicElement,nsSVGGraphicElementBase)NS_INTERFACE_MAP_BEGIN(nsSVGGraphicElement)NS_INTERFACE_MAP_ENTRY(nsIDOMSVGLocatable)NS_INTERFACE_MAP_ENTRY(nsIDOMSVGTransformable)NS_INTERFACE_MAP_END_INHERITING(nsSVGGraphicElementBase)//----------------------------------------------------------------------// ImplementationnsSVGGraphicElement::nsSVGGraphicElement(already_AddRefed<nsINodeInfo>aNodeInfo):nsSVGGraphicElementBase(aNodeInfo){}//----------------------------------------------------------------------// nsIDOMSVGLocatable methods/* readonly attribute nsIDOMSVGElement nearestViewportElement; */NS_IMETHODIMPnsSVGGraphicElement::GetNearestViewportElement(nsIDOMSVGElement**aNearestViewportElement){*aNearestViewportElement=nsSVGUtils::GetNearestViewportElement(this).get();returnNS_OK;}/* readonly attribute nsIDOMSVGElement farthestViewportElement; */NS_IMETHODIMPnsSVGGraphicElement::GetFarthestViewportElement(nsIDOMSVGElement**aFarthestViewportElement){NS_IF_ADDREF(*aFarthestViewportElement=nsSVGUtils::GetOuterSVGElement(this));returnNS_OK;}/* nsIDOMSVGRect getBBox (); */NS_IMETHODIMPnsSVGGraphicElement::GetBBox(nsIDOMSVGRect**_retval){*_retval=nsnull;nsIFrame*frame=GetPrimaryFrame(Flush_Layout);if(!frame||(frame->GetStateBits()&NS_STATE_SVG_NONDISPLAY_CHILD))returnNS_ERROR_FAILURE;nsISVGChildFrame*svgframe=do_QueryFrame(frame);if(svgframe){returnNS_NewSVGRect(_retval,nsSVGUtils::GetBBox(frame));}returnNS_ERROR_FAILURE;}/* nsIDOMSVGMatrix getCTM (); */NS_IMETHODIMPnsSVGGraphicElement::GetCTM(nsIDOMSVGMatrix**aCTM){gfxMatrixm=nsSVGUtils::GetCTM(this,false);*aCTM=m.IsSingular()?nsnull:newDOMSVGMatrix(m);NS_IF_ADDREF(*aCTM);returnNS_OK;}/* nsIDOMSVGMatrix getScreenCTM (); */NS_IMETHODIMPnsSVGGraphicElement::GetScreenCTM(nsIDOMSVGMatrix**aCTM){gfxMatrixm=nsSVGUtils::GetCTM(this,true);*aCTM=m.IsSingular()?nsnull:newDOMSVGMatrix(m);NS_IF_ADDREF(*aCTM);returnNS_OK;}/* nsIDOMSVGMatrix getTransformToElement (in nsIDOMSVGElement element); */NS_IMETHODIMPnsSVGGraphicElement::GetTransformToElement(nsIDOMSVGElement*element,nsIDOMSVGMatrix**_retval){if(!element)returnNS_ERROR_DOM_SVG_WRONG_TYPE_ERR;nsresultrv;*_retval=nsnull;nsCOMPtr<nsIDOMSVGMatrix>ourScreenCTM;nsCOMPtr<nsIDOMSVGMatrix>targetScreenCTM;nsCOMPtr<nsIDOMSVGMatrix>tmp;nsCOMPtr<nsIDOMSVGLocatable>target=do_QueryInterface(element,&rv);if(NS_FAILED(rv))returnrv;// the easiest way to do this (if likely to increase rounding error):GetScreenCTM(getter_AddRefs(ourScreenCTM));if(!ourScreenCTM)returnNS_ERROR_DOM_SVG_MATRIX_NOT_INVERTABLE;target->GetScreenCTM(getter_AddRefs(targetScreenCTM));if(!targetScreenCTM)returnNS_ERROR_DOM_SVG_MATRIX_NOT_INVERTABLE;rv=targetScreenCTM->Inverse(getter_AddRefs(tmp));if(NS_FAILED(rv))returnrv;returntmp->Multiply(ourScreenCTM,_retval);// addrefs, so we don't}//----------------------------------------------------------------------// nsIDOMSVGTransformable methods/* readonly attribute nsIDOMSVGAnimatedTransformList transform; */NS_IMETHODIMPnsSVGGraphicElement::GetTransform(nsIDOMSVGAnimatedTransformList**aTransform){*aTransform=DOMSVGAnimatedTransformList::GetDOMWrapper(GetAnimatedTransformList(),this).get();returnNS_OK;}//----------------------------------------------------------------------// nsIContent methodsNS_IMETHODIMP_(bool)nsSVGGraphicElement::IsAttributeMapped(constnsIAtom*name)const{staticconstMappedAttributeEntry*constmap[]={sColorMap,sFillStrokeMap,sGraphicsMap};returnFindAttributeDependence(name,map,ArrayLength(map))||nsSVGGraphicElementBase::IsAttributeMapped(name);}//----------------------------------------------------------------------// nsSVGElement overridesboolnsSVGGraphicElement::IsEventName(nsIAtom*aName){returnnsContentUtils::IsEventAttributeName(aName,EventNameType_SVGGraphic);}gfxMatrixnsSVGGraphicElement::PrependLocalTransformTo(constgfxMatrix&aMatrix)const{gfxMatrixresult(aMatrix);// animateMotion's resulting transform is supposed to apply *on top of*// any transformations from the |transform| attribute. So since we're// PRE-multiplying, we need to apply the animateMotion transform *first*.if(mAnimateMotionTransform){result.PreMultiply(*mAnimateMotionTransform);}if(mTransforms){result.PreMultiply(mTransforms->GetAnimValue().GetConsolidationMatrix());}returnresult;}voidnsSVGGraphicElement::SetAnimateMotionTransform(constgfxMatrix*aMatrix){mAnimateMotionTransform=aMatrix?newgfxMatrix(*aMatrix):nsnull;DidAnimateTransformList();}SVGAnimatedTransformList*nsSVGGraphicElement::GetAnimatedTransformList(){if(!mTransforms){mTransforms=newSVGAnimatedTransformList();}returnmTransforms;}