Back to index

lightning-sunbird  0.9+nobinonly
nsSVGLineFrame.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 "nsIDOMSVGLineElement.h"
00045 #include "nsIDOMSVGElement.h"
00046 #include "nsIDOMSVGSVGElement.h"
00047 #include "nsISVGRendererPathBuilder.h"
00048 #include "nsISVGMarkable.h"
00049 #include "nsLayoutAtoms.h"
00050 
00051 class nsSVGLineFrame : public nsSVGPathGeometryFrame,
00052                        public nsISVGMarkable
00053 {
00054 protected:
00055   friend nsresult
00056   NS_NewSVGLineFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsIFrame** aNewFrame);
00057 
00058   virtual ~nsSVGLineFrame();
00059   NS_IMETHOD InitSVG();
00060 
00066   virtual nsIAtom* GetType() const;
00067 
00068 #ifdef DEBUG
00069   NS_IMETHOD GetFrameName(nsAString& aResult) const
00070   {
00071     return MakeFrameName(NS_LITERAL_STRING("SVGLine"), aResult);
00072   }
00073 #endif
00074 
00075 public:
00076   // nsISVGValueObserver interface:
00077   NS_IMETHOD DidModifySVGObservable(nsISVGValue* observable,
00078                                     nsISVGValue::modificationType aModType);
00079 
00080   // nsISVGPathGeometrySource interface:
00081   NS_IMETHOD ConstructPath(nsISVGRendererPathBuilder *pathBuilder);
00082 
00083   // nsISVGMarkable interface
00084   void GetMarkPoints(nsVoidArray *aMarks);
00085 
00086    // nsISupports interface:
00087   NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
00088 
00089 private:
00090   NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
00091   NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }  
00092 
00093   nsCOMPtr<nsIDOMSVGLength> mX1;
00094   nsCOMPtr<nsIDOMSVGLength> mY1;
00095   nsCOMPtr<nsIDOMSVGLength> mX2;
00096   nsCOMPtr<nsIDOMSVGLength> mY2;
00097 };
00098 
00099 NS_INTERFACE_MAP_BEGIN(nsSVGLineFrame)
00100   NS_INTERFACE_MAP_ENTRY(nsISVGMarkable)
00101 NS_INTERFACE_MAP_END_INHERITING(nsSVGPathGeometryFrame)
00102 
00103 //----------------------------------------------------------------------
00104 // Implementation
00105 
00106 nsresult
00107 NS_NewSVGLineFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsIFrame** aNewFrame)
00108 {
00109   *aNewFrame = nsnull;
00110 
00111   nsCOMPtr<nsIDOMSVGLineElement> line = do_QueryInterface(aContent);
00112   if (!line) {
00113 #ifdef DEBUG
00114     printf("warning: trying to construct an SVGLineFrame for a content element that doesn't support the right interfaces\n");
00115 #endif
00116     return NS_ERROR_FAILURE;
00117   }
00118 
00119   nsSVGLineFrame* it = new (aPresShell) nsSVGLineFrame;
00120   if (nsnull == it)
00121     return NS_ERROR_OUT_OF_MEMORY;
00122 
00123   *aNewFrame = it;
00124   return NS_OK;
00125 }
00126 
00127 nsSVGLineFrame::~nsSVGLineFrame()
00128 {
00129   nsCOMPtr<nsISVGValue> value;
00130   if (mX1 && (value = do_QueryInterface(mX1)))
00131       value->RemoveObserver(this);
00132   if (mY1 && (value = do_QueryInterface(mY1)))
00133       value->RemoveObserver(this);
00134   if (mX2 && (value = do_QueryInterface(mX2)))
00135       value->RemoveObserver(this);
00136   if (mY2 && (value = do_QueryInterface(mY2)))
00137       value->RemoveObserver(this);
00138 }
00139 
00140 NS_IMETHODIMP
00141 nsSVGLineFrame::InitSVG()
00142 {
00143   nsresult rv = nsSVGPathGeometryFrame::InitSVG();
00144   if (NS_FAILED(rv)) return rv;
00145   
00146   nsCOMPtr<nsIDOMSVGLineElement> line = do_QueryInterface(mContent);
00147   NS_ASSERTION(line,"wrong content element");
00148 
00149   {
00150     nsCOMPtr<nsIDOMSVGAnimatedLength> length;
00151     line->GetX1(getter_AddRefs(length));
00152     length->GetAnimVal(getter_AddRefs(mX1));
00153     NS_ASSERTION(mX1, "no x1");
00154     if (!mX1) return NS_ERROR_FAILURE;
00155     nsCOMPtr<nsISVGValue> value = do_QueryInterface(mX1);
00156     if (value)
00157       value->AddObserver(this);
00158   }
00159 
00160   {
00161     nsCOMPtr<nsIDOMSVGAnimatedLength> length;
00162     line->GetY1(getter_AddRefs(length));
00163     length->GetAnimVal(getter_AddRefs(mY1));
00164     NS_ASSERTION(mY1, "no y1");
00165     if (!mY1) return NS_ERROR_FAILURE;
00166     nsCOMPtr<nsISVGValue> value = do_QueryInterface(mY1);
00167     if (value)
00168       value->AddObserver(this);
00169   }
00170 
00171   {
00172     nsCOMPtr<nsIDOMSVGAnimatedLength> length;
00173     line->GetX2(getter_AddRefs(length));
00174     length->GetAnimVal(getter_AddRefs(mX2));
00175     NS_ASSERTION(mX2, "no x2");
00176     if (!mX2) return NS_ERROR_FAILURE;
00177     nsCOMPtr<nsISVGValue> value = do_QueryInterface(mX2);
00178     if (value)
00179       value->AddObserver(this);
00180   }
00181 
00182   {
00183     nsCOMPtr<nsIDOMSVGAnimatedLength> length;
00184     line->GetY2(getter_AddRefs(length));
00185     length->GetAnimVal(getter_AddRefs(mY2));
00186     NS_ASSERTION(mY2, "no y2");
00187     if (!mY2) return NS_ERROR_FAILURE;
00188     nsCOMPtr<nsISVGValue> value = do_QueryInterface(mY2);
00189     if (value)
00190       value->AddObserver(this);
00191   }
00192 
00193   return NS_OK; 
00194 }
00195 
00196 nsIAtom *
00197 nsSVGLineFrame::GetType() const
00198 {
00199   return nsLayoutAtoms::svgLineFrame;
00200 }
00201 
00202 //----------------------------------------------------------------------
00203 // nsISVGValueObserver methods:
00204 
00205 NS_IMETHODIMP
00206 nsSVGLineFrame::DidModifySVGObservable(nsISVGValue* observable,
00207                                        nsISVGValue::modificationType aModType)
00208 {
00209   nsCOMPtr<nsIDOMSVGLength> l = do_QueryInterface(observable);
00210   if (l && (mX1==l || mY1==l || mX2==l || mY2==l)) {
00211     UpdateGraphic(nsISVGPathGeometrySource::UPDATEMASK_PATH);
00212     return NS_OK;
00213   }
00214   // else
00215   return nsSVGPathGeometryFrame::DidModifySVGObservable(observable, aModType);
00216 }
00217 
00218 //----------------------------------------------------------------------
00219 // nsISVGPathGeometrySource methods:
00220 
00221 /* void constructPath (in nsISVGRendererPathBuilder pathBuilder); */
00222 NS_IMETHODIMP nsSVGLineFrame::ConstructPath(nsISVGRendererPathBuilder* pathBuilder)
00223 {
00224   float x1,y1,x2,y2;
00225 
00226   mX1->GetValue(&x1);
00227   mY1->GetValue(&y1);
00228   mX2->GetValue(&x2);
00229   mY2->GetValue(&y2);
00230 
00231   // move to start coordinates then draw line to end coordinates
00232   pathBuilder->Moveto(x1, y1);
00233   pathBuilder->Lineto(x2, y2);
00234 
00235   return NS_OK;
00236 }
00237 
00238 //----------------------------------------------------------------------
00239 // nsISVGMarkable methods:
00240 
00241 void
00242 nsSVGLineFrame::GetMarkPoints(nsVoidArray *aMarks) {
00243   float x1,y1,x2,y2;
00244 
00245   mX1->GetValue(&x1);
00246   mY1->GetValue(&y1);
00247   mX2->GetValue(&x2);
00248   mY2->GetValue(&y2);
00249 
00250   nsSVGMark *m1, *m2;
00251   m1 = new nsSVGMark();
00252   m2 = new nsSVGMark();
00253 
00254   m1->x = x1;
00255   m1->y = y1;
00256   m2->x = x2;
00257   m2->y = y2;
00258   m1->angle = m2->angle = atan2(y2-y1, x2-x1);
00259 
00260   aMarks->AppendElement(m1);
00261   aMarks->AppendElement(m2);
00262 }