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
00040
00041 #include "nsSVGPathGeometryFrame.h"
00042 #include "nsIDOMSVGAnimatedLength.h"
00043 #include "nsIDOMSVGLength.h"
00044 #include "nsIDOMSVGPoint.h"
00045 #include "nsIDOMSVGRectElement.h"
00046 #include "nsIDOMSVGElement.h"
00047 #include "nsIDOMSVGSVGElement.h"
00048
00049 #include "nsISVGRendererPathBuilder.h"
00050
00051 class nsSVGRectFrame : public nsSVGPathGeometryFrame
00052 {
00053 protected:
00054 friend nsresult
00055 NS_NewSVGRectFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsIFrame** aNewFrame);
00056
00057 virtual ~nsSVGRectFrame();
00058 virtual nsresult Init();
00059
00060 public:
00061
00062 NS_IMETHOD DidModifySVGObservable(nsISVGValue* observable);
00063
00064
00065 NS_IMETHOD ConstructPath(nsISVGRendererPathBuilder *pathBuilder);
00066
00067 private:
00068 nsCOMPtr<nsIDOMSVGLength> mX;
00069 nsCOMPtr<nsIDOMSVGLength> mY;
00070 nsCOMPtr<nsIDOMSVGLength> mWidth;
00071 nsCOMPtr<nsIDOMSVGLength> mHeight;
00072 nsCOMPtr<nsIDOMSVGLength> mRx;
00073 nsCOMPtr<nsIDOMSVGLength> mRy;
00074 };
00075
00076
00077
00078
00079 nsresult
00080 NS_NewSVGRectFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsIFrame** aNewFrame)
00081 {
00082 *aNewFrame = nsnull;
00083
00084 nsCOMPtr<nsIDOMSVGRectElement> Rect = do_QueryInterface(aContent);
00085 if (!Rect) {
00086 #ifdef DEBUG
00087 printf("warning: trying to construct an SVGRectFrame for a content element that doesn't support the right interfaces\n");
00088 #endif
00089 return NS_ERROR_FAILURE;
00090 }
00091
00092 nsSVGRectFrame* it = new (aPresShell) nsSVGRectFrame;
00093 if (nsnull == it)
00094 return NS_ERROR_OUT_OF_MEMORY;
00095
00096 *aNewFrame = it;
00097 return NS_OK;
00098 }
00099
00100 nsSVGRectFrame::~nsSVGRectFrame()
00101 {
00102 nsCOMPtr<nsISVGValue> value;
00103 if (mX && (value = do_QueryInterface(mX)))
00104 value->RemoveObserver(this);
00105 if (mY && (value = do_QueryInterface(mY)))
00106 value->RemoveObserver(this);
00107 if (mWidth && (value = do_QueryInterface(mWidth)))
00108 value->RemoveObserver(this);
00109 if (mHeight && (value = do_QueryInterface(mHeight)))
00110 value->RemoveObserver(this);
00111 if (mRx && (value = do_QueryInterface(mRx)))
00112 value->RemoveObserver(this);
00113 if (mRy && (value = do_QueryInterface(mRy)))
00114 value->RemoveObserver(this);
00115 }
00116
00117 nsresult nsSVGRectFrame::Init()
00118 {
00119 nsresult rv = nsSVGPathGeometryFrame::Init();
00120 if (NS_FAILED(rv)) return rv;
00121
00122 nsCOMPtr<nsIDOMSVGRectElement> Rect = do_QueryInterface(mContent);
00123 NS_ASSERTION(Rect,"wrong content element");
00124
00125 {
00126 nsCOMPtr<nsIDOMSVGAnimatedLength> length;
00127 Rect->GetX(getter_AddRefs(length));
00128 length->GetBaseVal(getter_AddRefs(mX));
00129 NS_ASSERTION(mX, "no x");
00130 if (!mX) return NS_ERROR_FAILURE;
00131 nsCOMPtr<nsISVGValue> value = do_QueryInterface(mX);
00132 if (value)
00133 value->AddObserver(this);
00134 }
00135
00136 {
00137 nsCOMPtr<nsIDOMSVGAnimatedLength> length;
00138 Rect->GetY(getter_AddRefs(length));
00139 length->GetBaseVal(getter_AddRefs(mY));
00140 NS_ASSERTION(mY, "no y");
00141 if (!mY) return NS_ERROR_FAILURE;
00142 nsCOMPtr<nsISVGValue> value = do_QueryInterface(mY);
00143 if (value)
00144 value->AddObserver(this);
00145 }
00146
00147 {
00148 nsCOMPtr<nsIDOMSVGAnimatedLength> length;
00149 Rect->GetWidth(getter_AddRefs(length));
00150 length->GetBaseVal(getter_AddRefs(mWidth));
00151 NS_ASSERTION(mWidth, "no width");
00152 if (!mWidth) return NS_ERROR_FAILURE;
00153 nsCOMPtr<nsISVGValue> value = do_QueryInterface(mWidth);
00154 if (value)
00155 value->AddObserver(this);
00156 }
00157 {
00158 nsCOMPtr<nsIDOMSVGAnimatedLength> length;
00159 Rect->GetHeight(getter_AddRefs(length));
00160 length->GetBaseVal(getter_AddRefs(mHeight));
00161 NS_ASSERTION(mHeight, "no height");
00162 if (!mHeight) return NS_ERROR_FAILURE;
00163 nsCOMPtr<nsISVGValue> value = do_QueryInterface(mHeight);
00164 if (value)
00165 value->AddObserver(this);
00166 }
00167
00168 {
00169 nsCOMPtr<nsIDOMSVGAnimatedLength> length;
00170 Rect->GetRx(getter_AddRefs(length));
00171 length->GetBaseVal(getter_AddRefs(mRx));
00172 NS_ASSERTION(mRx, "no rx");
00173 if (!mRx) return NS_ERROR_FAILURE;
00174 nsCOMPtr<nsISVGValue> value = do_QueryInterface(mRx);
00175 if (value)
00176 value->AddObserver(this);
00177 }
00178
00179 {
00180 nsCOMPtr<nsIDOMSVGAnimatedLength> length;
00181 Rect->GetRy(getter_AddRefs(length));
00182 length->GetBaseVal(getter_AddRefs(mRy));
00183 NS_ASSERTION(mRy, "no ry");
00184 if (!mRy) return NS_ERROR_FAILURE;
00185 nsCOMPtr<nsISVGValue> value = do_QueryInterface(mRy);
00186 if (value)
00187 value->AddObserver(this);
00188 }
00189
00190 return NS_OK;
00191 }
00192
00193
00194
00195
00196 NS_IMETHODIMP
00197 nsSVGRectFrame::DidModifySVGObservable(nsISVGValue* observable)
00198 {
00199 nsCOMPtr<nsIDOMSVGLength> l = do_QueryInterface(observable);
00200 if (l && (mX==l || mY==l || mWidth==l || mHeight==l || mRx==l || mRy==l)) {
00201 UpdateGraphic(nsISVGPathGeometrySource::UPDATEMASK_PATH);
00202 return NS_OK;
00203 }
00204
00205 return nsSVGPathGeometryFrame::DidModifySVGObservable(observable);
00206 }
00207
00208
00209
00210
00211
00212 NS_IMETHODIMP nsSVGRectFrame::ConstructPath(nsISVGRendererPathBuilder* pathBuilder)
00213 {
00214 float x, y, width, height, rx, ry;
00215
00216 mX->GetValue(&x);
00217 mY->GetValue(&y);
00218 mWidth->GetValue(&width);
00219 mHeight->GetValue(&height);
00220 mRx->GetValue(&rx);
00221 mRy->GetValue(&ry);
00222
00223
00224
00225 if (width == 0 || height == 0 || ry < 0 || rx < 0)
00226 return NS_OK;
00227
00228
00229
00230 if (!rx || !ry)
00231 {
00232 if (rx < ry)
00233 rx = ry;
00234 else
00235 ry = rx;
00236 }
00237
00238
00239 if (rx > (width/2))
00240 rx = width/2;
00241
00242 if (ry > (height/2))
00243 ry = height/2;
00244
00245 pathBuilder->Moveto(x+rx, y);
00246 pathBuilder->Lineto(x+width-rx, y);
00247 pathBuilder->Arcto(x+width, y+ry , rx, ry, 0.0, 0, 1);
00248 pathBuilder->Lineto(x+width, y+height-ry);
00249 pathBuilder->Arcto(x+width-rx, y+height , rx, ry, 0.0, 0, 1);
00250 pathBuilder->Lineto(x+rx,y+height);
00251 pathBuilder->Arcto(x, y+height-ry , rx, ry, 0.0, 0, 1);
00252 pathBuilder->Lineto(x,y+ry);
00253 pathBuilder->Arcto(x+rx, y, rx, ry, 0.0, 0, 1);
00254 pathBuilder->ClosePath(&x,&y);
00255
00256 return NS_OK;
00257 }