/layout/svg/renderer/src/gdiplus/nsSVGGDIPlusRegion.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
00006  * Version 1.1 (the "License"); you may not use this file except in
00007  * compliance with 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) 2002
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *    Alex Fritze <alex.fritze@crocodile-clips.com> (original author)
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or 
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the NPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ----- END LICENSE BLOCK ----- */
00038 
00039 #include <windows.h>
00040 
00041 // unknwn.h is needed to build with WIN32_LEAN_AND_MEAN
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   // nsISupports interface:
00086   NS_DECL_ISUPPORTS
00087 
00088   // nsISVGGDIPlusRegion interface:
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   // nsISVGRendererRegion interface:
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 // implementation:
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     // this better be what we think it is:
00198     win = (HWND)((nsDeviceContextWin *)(devicecontext.get()))->mWidget;
00199     devicehandle = ::GetDC(win);
00200   }
00201 
00202   {
00203     // wrap this in a block so that the Graphics-object goes out of
00204     // scope before we release the HDC.
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 // nsISupports methods:
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 // nsISVGGDIPlusRegion methods:
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 // nsISVGRendererRegion methods:
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 }

Generated on Wed Sep 10 22:25:24 2003 for Mozilla SVG Project Rendering Backend by doxygen1.3