Back to index

lightning-sunbird  0.9+nobinonly
nsSVGEllipseFrame.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is the Mozilla SVG project.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Crocodile Clips Ltd..
00019  * Portions created by the Initial Developer are Copyright (C) 2001
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   William Cook <william.cook@crocodile-clips.com> (original author)
00024  *   Alex Fritze <alex.fritze@crocodile-clips.com>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #include "nsSVGPathGeometryFrame.h"
00041 #include "nsIDOMSVGAnimatedLength.h"
00042 #include "nsIDOMSVGLength.h"
00043 #include "nsIDOMSVGPoint.h"
00044 #include "nsIDOMSVGEllipseElement.h"
00045 #include "nsIDOMSVGElement.h"
00046 #include "nsIDOMSVGSVGElement.h"
00047 #include "nsISVGRendererPathBuilder.h"
00048 #include "nsLayoutAtoms.h"
00049 
00050 class nsSVGEllipseFrame : public nsSVGPathGeometryFrame
00051 {
00052   friend nsresult
00053   NS_NewSVGEllipseFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsIFrame** aNewFrame);
00054 
00055   virtual ~nsSVGEllipseFrame();
00056 
00057   NS_IMETHOD InitSVG();
00058 
00064   virtual nsIAtom* GetType() const;
00065 
00066 #ifdef DEBUG
00067   NS_IMETHOD GetFrameName(nsAString& aResult) const
00068   {
00069     return MakeFrameName(NS_LITERAL_STRING("SVGEllipse"), aResult);
00070   }
00071 #endif
00072 
00073   // nsISVGValueObserver interface:
00074   NS_IMETHOD DidModifySVGObservable(nsISVGValue* observable,
00075                                     nsISVGValue::modificationType aModType);
00076 
00077   // nsISVGPathGeometrySource interface:
00078   NS_IMETHOD ConstructPath(nsISVGRendererPathBuilder *pathBuilder);
00079 
00080   nsCOMPtr<nsIDOMSVGLength> mCx;
00081   nsCOMPtr<nsIDOMSVGLength> mCy;
00082   nsCOMPtr<nsIDOMSVGLength> mRx;
00083   nsCOMPtr<nsIDOMSVGLength> mRy;
00084 };
00085 
00086 //----------------------------------------------------------------------
00087 // Implementation
00088 
00089 nsresult
00090 NS_NewSVGEllipseFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsIFrame** aNewFrame)
00091 {
00092   *aNewFrame = nsnull;
00093 
00094   nsCOMPtr<nsIDOMSVGEllipseElement> ellipse = do_QueryInterface(aContent);
00095   if (!ellipse) {
00096 #ifdef DEBUG
00097     printf("warning: trying to construct an SVGEllipseFrame for a content element that doesn't support the right interfaces\n");
00098 #endif
00099     return NS_ERROR_FAILURE;
00100   }
00101 
00102   nsSVGEllipseFrame* it = new (aPresShell) nsSVGEllipseFrame;
00103   if (nsnull == it)
00104     return NS_ERROR_OUT_OF_MEMORY;
00105 
00106   *aNewFrame = it;
00107   return NS_OK;
00108 }
00109 
00110 nsSVGEllipseFrame::~nsSVGEllipseFrame()
00111 {
00112   nsCOMPtr<nsISVGValue> value;
00113   if (mCx && (value = do_QueryInterface(mCx)))
00114       value->RemoveObserver(this);
00115   if (mCy && (value = do_QueryInterface(mCy)))
00116       value->RemoveObserver(this);
00117   if (mRx && (value = do_QueryInterface(mRx)))
00118       value->RemoveObserver(this);
00119   if (mRy && (value = do_QueryInterface(mRy)))
00120       value->RemoveObserver(this);
00121 }
00122 
00123 NS_IMETHODIMP
00124 nsSVGEllipseFrame::InitSVG()
00125 {
00126   nsresult rv = nsSVGPathGeometryFrame::InitSVG();
00127   if (NS_FAILED(rv)) return rv;
00128   
00129   nsCOMPtr<nsIDOMSVGEllipseElement> ellipse = do_QueryInterface(mContent);
00130   NS_ASSERTION(ellipse,"wrong content element");
00131 
00132   {
00133     nsCOMPtr<nsIDOMSVGAnimatedLength> length;
00134     ellipse->GetCx(getter_AddRefs(length));
00135     length->GetAnimVal(getter_AddRefs(mCx));
00136     NS_ASSERTION(mCx, "no cx");
00137     if (!mCx) return NS_ERROR_FAILURE;
00138     nsCOMPtr<nsISVGValue> value = do_QueryInterface(mCx);
00139     if (value)
00140       value->AddObserver(this);
00141   }
00142 
00143   {
00144     nsCOMPtr<nsIDOMSVGAnimatedLength> length;
00145     ellipse->GetCy(getter_AddRefs(length));
00146     length->GetAnimVal(getter_AddRefs(mCy));
00147     NS_ASSERTION(mCy, "no cy");
00148     if (!mCy) return NS_ERROR_FAILURE;
00149     nsCOMPtr<nsISVGValue> value = do_QueryInterface(mCy);
00150     if (value)
00151       value->AddObserver(this);
00152   }
00153 
00154   {
00155     nsCOMPtr<nsIDOMSVGAnimatedLength> length;
00156     ellipse->GetRx(getter_AddRefs(length));
00157     length->GetAnimVal(getter_AddRefs(mRx));
00158     NS_ASSERTION(mRx, "no rx");
00159     if (!mRx) return NS_ERROR_FAILURE;
00160     nsCOMPtr<nsISVGValue> value = do_QueryInterface(mRx);
00161     if (value)
00162       value->AddObserver(this);
00163   }
00164 
00165   {
00166     nsCOMPtr<nsIDOMSVGAnimatedLength> length;
00167     ellipse->GetRy(getter_AddRefs(length));
00168     length->GetAnimVal(getter_AddRefs(mRy));
00169     NS_ASSERTION(mRy, "no ry");
00170     if (!mRy) return NS_ERROR_FAILURE;
00171     nsCOMPtr<nsISVGValue> value = do_QueryInterface(mRy);
00172     if (value)
00173       value->AddObserver(this);
00174   }
00175 
00176   return NS_OK; 
00177 }
00178 
00179 nsIAtom *
00180 nsSVGEllipseFrame::GetType() const
00181 {
00182   return nsLayoutAtoms::svgEllipseFrame;
00183 }
00184 
00185 //----------------------------------------------------------------------
00186 // nsISVGValueObserver methods:
00187 
00188 NS_IMETHODIMP
00189 nsSVGEllipseFrame::DidModifySVGObservable(nsISVGValue* observable,
00190                                           nsISVGValue::modificationType aModType)
00191 {
00192   nsCOMPtr<nsIDOMSVGLength> l = do_QueryInterface(observable);
00193   if (l && (mCx==l || mCy==l || mRx==l || mRy==l)) {
00194     UpdateGraphic(nsISVGPathGeometrySource::UPDATEMASK_PATH);
00195     return NS_OK;
00196   }
00197   // else
00198   return nsSVGPathGeometryFrame::DidModifySVGObservable(observable, aModType);
00199 }
00200 
00201 //----------------------------------------------------------------------
00202 // nsISVGPathGeometrySource methods:
00203 
00204 /* void constructPath (in nsISVGRendererPathBuilder pathBuilder); */
00205 NS_IMETHODIMP nsSVGEllipseFrame::ConstructPath(nsISVGRendererPathBuilder* pathBuilder)
00206 {
00207   float x,y,rx,ry;
00208 
00209   mCx->GetValue(&x);
00210   mCy->GetValue(&y);
00211   mRx->GetValue(&rx);
00212   mRy->GetValue(&ry);
00213 
00214   // build ellipse from two arcs
00215   pathBuilder->Moveto(x-rx, y);
00216   pathBuilder->Arcto(x+rx, y, rx, ry, 0.0, 0, 0);
00217   pathBuilder->Arcto(x-rx, y, rx, ry, 0.0, 1, 0);
00218   pathBuilder->ClosePath(&x,&y);
00219 
00220   return NS_OK;
00221 }