00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "nsSVGPathGeometryFrame.h"
00040 #include "nsIDOMSVGAnimatedLength.h"
00041 #include "nsIDOMSVGLength.h"
00042 #include "nsIDOMSVGPoint.h"
00043 #include "nsIDOMSVGCircleElement.h"
00044 #include "nsIDOMSVGElement.h"
00045 #include "nsIDOMSVGSVGElement.h"
00046
00047 #include "nsISVGRendererPathBuilder.h"
00048
00049 class nsSVGCircleFrame : public nsSVGPathGeometryFrame
00050 {
00051 protected:
00052 friend nsresult
00053 NS_NewSVGCircleFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsIFrame** aNewFrame);
00054
00055 virtual ~nsSVGCircleFrame();
00056 virtual nsresult Init();
00057
00058 public:
00059
00060 NS_IMETHOD DidModifySVGObservable(nsISVGValue* observable);
00061
00062
00063 NS_IMETHOD ConstructPath(nsISVGRendererPathBuilder *pathBuilder);
00064
00065 private:
00066 nsCOMPtr<nsIDOMSVGLength> mCx;
00067 nsCOMPtr<nsIDOMSVGLength> mCy;
00068 nsCOMPtr<nsIDOMSVGLength> mR;
00069 };
00070
00071
00072
00073
00074 nsresult
00075 NS_NewSVGCircleFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsIFrame** aNewFrame)
00076 {
00077 *aNewFrame = nsnull;
00078
00079 nsCOMPtr<nsIDOMSVGCircleElement> circle = do_QueryInterface(aContent);
00080 if (!circle) {
00081 #ifdef DEBUG
00082 printf("warning: trying to construct an SVGCircleFrame for a content element that doesn't support the right interfaces\n");
00083 #endif
00084 return NS_ERROR_FAILURE;
00085 }
00086
00087 nsSVGCircleFrame* it = new (aPresShell) nsSVGCircleFrame;
00088 if (nsnull == it)
00089 return NS_ERROR_OUT_OF_MEMORY;
00090
00091 *aNewFrame = it;
00092 return NS_OK;
00093 }
00094
00095 nsSVGCircleFrame::~nsSVGCircleFrame()
00096 {
00097 nsCOMPtr<nsISVGValue> value;
00098 if (mCx && (value = do_QueryInterface(mCx)))
00099 value->RemoveObserver(this);
00100 if (mCy && (value = do_QueryInterface(mCy)))
00101 value->RemoveObserver(this);
00102 if (mR && (value = do_QueryInterface(mR)))
00103 value->RemoveObserver(this);
00104 }
00105
00106 nsresult nsSVGCircleFrame::Init()
00107 {
00108 nsresult rv = nsSVGPathGeometryFrame::Init();
00109 if (NS_FAILED(rv)) return rv;
00110
00111
00112 nsCOMPtr<nsIDOMSVGCircleElement> circle = do_QueryInterface(mContent);
00113 NS_ASSERTION(circle,"wrong content element");
00114
00115 {
00116 nsCOMPtr<nsIDOMSVGAnimatedLength> length;
00117 circle->GetCx(getter_AddRefs(length));
00118 length->GetBaseVal(getter_AddRefs(mCx));
00119 NS_ASSERTION(mCx, "no cx");
00120 if (!mCx) return NS_ERROR_FAILURE;
00121 nsCOMPtr<nsISVGValue> value = do_QueryInterface(mCx);
00122 if (value)
00123 value->AddObserver(this);
00124 }
00125
00126 {
00127 nsCOMPtr<nsIDOMSVGAnimatedLength> length;
00128 circle->GetCy(getter_AddRefs(length));
00129 length->GetBaseVal(getter_AddRefs(mCy));
00130 NS_ASSERTION(mCx, "no cy");
00131 if (!mCx) return NS_ERROR_FAILURE;
00132 nsCOMPtr<nsISVGValue> value = do_QueryInterface(mCy);
00133 if (value)
00134 value->AddObserver(this);
00135 }
00136
00137 {
00138 nsCOMPtr<nsIDOMSVGAnimatedLength> length;
00139 circle->GetR(getter_AddRefs(length));
00140 length->GetBaseVal(getter_AddRefs(mR));
00141 NS_ASSERTION(mCx, "no r");
00142 if (!mCx) return NS_ERROR_FAILURE;
00143 nsCOMPtr<nsISVGValue> value = do_QueryInterface(mR);
00144 if (value)
00145 value->AddObserver(this);
00146 }
00147
00148 return NS_OK;
00149 }
00150
00151
00152
00153
00154 NS_IMETHODIMP
00155 nsSVGCircleFrame::DidModifySVGObservable(nsISVGValue* observable)
00156 {
00157 nsCOMPtr<nsIDOMSVGLength> l = do_QueryInterface(observable);
00158 if (l && (mCx==l || mCy==l || mR==l)) {
00159 UpdateGraphic(nsISVGPathGeometrySource::UPDATEMASK_PATH);
00160 return NS_OK;
00161 }
00162
00163 return nsSVGPathGeometryFrame::DidModifySVGObservable(observable);
00164 }
00165
00166
00167
00168
00169
00170
00171 NS_IMETHODIMP nsSVGCircleFrame::ConstructPath(nsISVGRendererPathBuilder* pathBuilder)
00172 {
00173 float x,y,r;
00174
00175 mCx->GetValue(&x);
00176 mCy->GetValue(&y);
00177 mR->GetValue(&r);
00178
00179
00180
00181
00182 pathBuilder->Moveto(x, y-r);
00183 pathBuilder->Arcto(x-r, y , r, r, 0.0, 0, 0);
00184 pathBuilder->Arcto(x , y-r, r, r, 0.0, 1, 0);
00185 pathBuilder->ClosePath(&x,&y);
00186
00187 return NS_OK;
00188 }