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 <windows.h>
00040
00041
00042 #include <unknwn.h>
00043
00044 #include <Gdiplus.h>
00045 using namespace Gdiplus;
00046
00047 #include "nsCOMPtr.h"
00048 #include "nsISVGGDIPlusRegion.h"
00049 #include "nsSVGGDIPlusRegion.h"
00050 #include "nsISVGRectangleSink.h"
00051 #include "nsIPresContext.h"
00052 #include "nsDeviceContextWin.h"
00053
00058
00059
00062 class nsSVGGDIPlusRegion : public nsISVGGDIPlusRegion
00063 {
00064 protected:
00065 friend nsresult NS_NewSVGGDIPlusRectRegion(nsISVGRendererRegion** result,
00066 float x, float y,
00067 float width, float height);
00068 friend nsresult NS_NewSVGGDIPlusPathRegion(nsISVGRendererRegion** result,
00069 const GraphicsPath* path);
00070 friend nsresult NS_NewSVGGDIPlusClonedRegion(nsISVGRendererRegion** result,
00071 const Region* region,
00072 nsIPresContext *presContext);
00073 nsSVGGDIPlusRegion(RectF& rect);
00074 nsSVGGDIPlusRegion(const GraphicsPath* path);
00075 nsSVGGDIPlusRegion(const nsSVGGDIPlusRegion& other);
00076 nsSVGGDIPlusRegion(const Region* other
00077 #ifdef NS_SVG_GDIPLUS_RENDERER_USE_RECT_REGIONS
00078 , const Graphics* graphics
00079 #endif
00080 );
00081
00082 ~nsSVGGDIPlusRegion();
00083
00084 public:
00085
00086 NS_DECL_ISUPPORTS
00087
00088
00089 #ifdef NS_SVG_GDIPLUS_RENDERER_USE_RECT_REGIONS
00090 NS_IMETHOD_(const RectF*) GetRect()const;
00091 #else
00092 NS_IMETHOD_(const Region*) GetRegion()const;
00093 #endif
00094
00095
00096 NS_DECL_NSISVGRENDERERREGION
00097
00098 private:
00099 #ifdef NS_SVG_GDIPLUS_RENDERER_USE_RECT_REGIONS
00100 RectF mRect;
00101 #else
00102 Region mRegion;
00103 #endif
00104 };
00105
00108
00109
00110
00111 nsSVGGDIPlusRegion::nsSVGGDIPlusRegion(RectF& rect)
00112 #ifdef NS_SVG_GDIPLUS_RENDERER_USE_RECT_REGIONS
00113 : mRect(rect.X, rect.Y, rect.Width, rect.Height)
00114 #else
00115 : mRegion(rect)
00116 #endif
00117 {
00118 }
00119
00120 nsSVGGDIPlusRegion::nsSVGGDIPlusRegion(const GraphicsPath* path)
00121 #ifndef NS_SVG_GDIPLUS_RENDERER_USE_RECT_REGIONS
00122 : mRegion(path)
00123 #endif
00124 {
00125 #ifdef NS_SVG_GDIPLUS_RENDERER_USE_RECT_REGIONS
00126 path->GetBounds(&mRect);
00127 #endif
00128 }
00129
00130 nsSVGGDIPlusRegion::nsSVGGDIPlusRegion(const nsSVGGDIPlusRegion& other)
00131 {
00132
00133 #ifdef NS_SVG_GDIPLUS_RENDERER_USE_RECT_REGIONS
00134 mRect.X = other.GetRect()->X;
00135 mRect.Y = other.GetRect()->Y;
00136 mRect.Width = other.GetRect()->Width;
00137 mRect.Height = other.GetRect()->Height;
00138 #else
00139 mRegion.MakeEmpty();
00140 mRegion.Union(other.GetRegion());
00141 #endif
00142 }
00143
00144 nsSVGGDIPlusRegion::nsSVGGDIPlusRegion(const Region* other
00145 #ifdef NS_SVG_GDIPLUS_RENDERER_USE_RECT_REGIONS
00146 , const Graphics* graphics
00147 #endif
00148 )
00149 {
00150
00151 #ifdef NS_SVG_GDIPLUS_RENDERER_USE_RECT_REGIONS
00152 other->GetBounds(&mRect, graphics);
00153 #else
00154 mRegion.MakeEmpty();
00155 mRegion.Union(other);
00156 #endif
00157 }
00158
00159
00160 nsSVGGDIPlusRegion::~nsSVGGDIPlusRegion()
00161 {
00162 }
00163
00164 nsresult
00165 NS_NewSVGGDIPlusRectRegion(nsISVGRendererRegion** result,
00166 float x, float y,
00167 float width, float height)
00168 {
00169 *result = new nsSVGGDIPlusRegion(RectF(x, y, width, height));
00170 if (!*result) return NS_ERROR_OUT_OF_MEMORY;
00171
00172 NS_ADDREF(*result);
00173 return NS_OK;
00174 }
00175
00176 nsresult
00177 NS_NewSVGGDIPlusPathRegion(nsISVGRendererRegion** result,
00178 const GraphicsPath* path)
00179 {
00180 *result = new nsSVGGDIPlusRegion(path);
00181 if (!*result) return NS_ERROR_OUT_OF_MEMORY;
00182
00183 NS_ADDREF(*result);
00184 return NS_OK;
00185 }
00186
00187 nsresult NS_NewSVGGDIPlusClonedRegion(nsISVGRendererRegion** result,
00188 const Region* region,
00189 nsIPresContext *presContext)
00190 {
00191 #ifdef NS_SVG_GDIPLUS_RENDERER_USE_RECT_REGIONS
00192 HWND win;
00193 HDC devicehandle;
00194 {
00195 nsCOMPtr<nsIDeviceContext> devicecontext;
00196 presContext->GetDeviceContext(getter_AddRefs(devicecontext));
00197
00198 win = (HWND)((nsDeviceContextWin *)(devicecontext.get()))->mWidget;
00199 devicehandle = ::GetDC(win);
00200 }
00201
00202 {
00203
00204
00205
00206 Graphics graphics(devicehandle);
00207
00208 *result = new nsSVGGDIPlusRegion(region, &graphics);
00209 }
00210
00211 ::ReleaseDC(win, devicehandle);
00212 #else
00213 *result = new nsSVGGDIPlusRegion(region);
00214 #endif
00215
00216 if (!*result) return NS_ERROR_OUT_OF_MEMORY;
00217
00218 NS_ADDREF(*result);
00219 return NS_OK;
00220 }
00221
00222
00223
00224
00225 NS_IMPL_ADDREF(nsSVGGDIPlusRegion)
00226 NS_IMPL_RELEASE(nsSVGGDIPlusRegion)
00227
00228 NS_INTERFACE_MAP_BEGIN(nsSVGGDIPlusRegion)
00229 NS_INTERFACE_MAP_ENTRY(nsISVGGDIPlusRegion)
00230 NS_INTERFACE_MAP_ENTRY(nsISVGRendererRegion)
00231 NS_INTERFACE_MAP_ENTRY(nsISupports)
00232 NS_INTERFACE_MAP_END
00233
00234
00235
00236
00237 #ifdef NS_SVG_GDIPLUS_RENDERER_USE_RECT_REGIONS
00238 NS_IMETHODIMP_(const RectF*)
00239 nsSVGGDIPlusRegion::GetRect()const
00240 {
00241 return &mRect;
00242 }
00243 #else
00244 NS_IMETHODIMP_(const Region*)
00245 nsSVGGDIPlusRegion::GetRegion()const
00246 {
00247 return &mRegion;
00248 }
00249 #endif
00250
00251
00252
00253
00255 NS_IMETHODIMP
00256 nsSVGGDIPlusRegion::Combine(nsISVGRendererRegion *other, nsISVGRendererRegion **_retval)
00257 {
00258 *_retval = nsnull;
00259
00260 nsSVGGDIPlusRegion *union_region = new nsSVGGDIPlusRegion(*this);
00261 NS_ADDREF(union_region);
00262 *_retval = union_region;
00263
00264 if (!other) return NS_OK;
00265
00266 nsCOMPtr<nsISVGGDIPlusRegion> other2 = do_QueryInterface(other);
00267 if (!other2) {
00268 NS_WARNING("Union operation on incompatible regions");
00269 return NS_OK;
00270 }
00271
00272 #ifdef NS_SVG_GDIPLUS_RENDERER_USE_RECT_REGIONS
00273 RectF::Union(union_region->mRect, mRect, *(other2->GetRect()));
00274 #else
00275 union_region->mRegion.Union(other2->GetRegion());
00276 #endif
00277
00278 return NS_OK;
00279 }
00280
00282 NS_IMETHODIMP
00283 nsSVGGDIPlusRegion::GetRectangleScans(nsISVGRectangleSink *sink)
00284 {
00285 #ifdef NS_SVG_GDIPLUS_RENDERER_USE_RECT_REGIONS
00286 sink->SinkRectangle(mRect.X-1, mRect.Y-1, mRect.Width+2, mRect.Height+2);
00287 #else
00288 Matrix matrix;
00289 INT count = mRegion.GetRegionScansCount(&matrix);
00290 if (count == 0) return NS_OK;
00291
00292 RectF* rects = (RectF*)malloc(count*sizeof(RectF));
00293 mRegion.GetRegionScans(&matrix, rects, &count);
00294
00295 for (INT i=0; i<count; ++i)
00296 sink->SinkRectangle(rects[i].X-1, rects[i].Y-1, rects[i].Width+2, rects[i].Height+2);
00297
00298 free(rects);
00299 #endif
00300
00301 return NS_OK;
00302 }