Back to index

lightning-sunbird  0.9+nobinonly
nsCairoRegion.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * mozilla.org.
00019  * Portions created by the Initial Developer are Copyright (C) 2004
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Stuart Parmenter <pavlov@pavlov.net>
00024  *   Joe Hewitt <hewitt@netscape.com>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either the GNU General Public License Version 2 or later (the "GPL"), or
00028  * 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 "nsCairoRegion.h"
00041 
00042 NS_IMPL_ISUPPORTS1(nsCairoRegion, nsIRegion)
00043 
00044 nsCairoRegion::nsCairoRegion() 
00045 {  
00046   NS_INIT_ISUPPORTS();
00047 }
00048 
00049 nsresult nsCairoRegion::Init (void)
00050 {
00051   mRegion.SetEmpty();
00052   return NS_OK;
00053 }
00054 
00055 void nsCairoRegion::SetTo (const nsIRegion &aRegion)
00056 {
00057   const nsCairoRegion* pRegion = NS_STATIC_CAST (const nsCairoRegion*, &aRegion);
00058   mRegion = pRegion->mRegion;
00059 }
00060 
00061 void nsCairoRegion::SetTo (PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
00062 {
00063   mRegion = nsRect (aX, aY, aWidth, aHeight);
00064 }
00065 
00066 void nsCairoRegion::Intersect (const nsIRegion &aRegion)
00067 {
00068   const nsCairoRegion* pRegion = NS_STATIC_CAST (const nsCairoRegion*, &aRegion);
00069   mRegion.And (mRegion, pRegion->mRegion);
00070 }
00071 
00072 void nsCairoRegion::Intersect (PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
00073 {
00074   mRegion.And (mRegion, nsRect (aX, aY, aWidth, aHeight));
00075 }
00076 
00077 void nsCairoRegion::Union (const nsIRegion &aRegion)
00078 {
00079   const nsCairoRegion* pRegion = NS_STATIC_CAST (const nsCairoRegion*, &aRegion);
00080   mRegion.Or (mRegion, pRegion->mRegion);
00081 }
00082 
00083 void nsCairoRegion::Union (PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
00084 {
00085   mRegion.Or (mRegion, nsRect (aX, aY, aWidth, aHeight));
00086 }
00087 
00088 void nsCairoRegion::Subtract (const nsIRegion &aRegion)
00089 {
00090   const nsCairoRegion* pRegion = NS_STATIC_CAST (const nsCairoRegion*, &aRegion);
00091   mRegion.Sub (mRegion, pRegion->mRegion);
00092 }
00093 
00094 void nsCairoRegion::Subtract (PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
00095 {
00096   mRegion.Sub (mRegion, nsRect (aX, aY, aWidth, aHeight));
00097 }
00098 
00099 PRBool nsCairoRegion::IsEmpty (void)
00100 {
00101   return mRegion.IsEmpty ();
00102 }
00103 
00104 PRBool nsCairoRegion::IsEqual (const nsIRegion &aRegion)
00105 {
00106   const nsCairoRegion* pRegion = NS_STATIC_CAST (const nsCairoRegion*, &aRegion);
00107   return mRegion.IsEqual (pRegion->mRegion);
00108 }
00109 
00110 void nsCairoRegion::GetBoundingBox (PRInt32 *aX, PRInt32 *aY, PRInt32 *aWidth, PRInt32 *aHeight)
00111 {
00112   nsRect BoundRect;
00113   BoundRect = mRegion.GetBounds();
00114   *aX = BoundRect.x;
00115   *aY = BoundRect.y;
00116   *aWidth  = BoundRect.width;
00117   *aHeight = BoundRect.height;
00118 }
00119 
00120 void nsCairoRegion::Offset (PRInt32 aXOffset, PRInt32 aYOffset)
00121 {
00122   mRegion.MoveBy (aXOffset, aYOffset);
00123 }
00124 
00125 PRBool nsCairoRegion::ContainsRect (PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
00126 {
00127   nsRegion TmpRegion;
00128   TmpRegion.And (mRegion, nsRect (aX, aY, aWidth, aHeight));
00129   return (!TmpRegion.IsEmpty ());
00130 }
00131 
00132 NS_IMETHODIMP
00133 nsCairoRegion::GetRects (nsRegionRectSet **aRects)
00134 {
00135   if (!aRects)
00136     return NS_ERROR_NULL_POINTER;
00137 
00138   nsRegionRectSet* pRegionSet = *aRects;
00139   PRUint32 NumRects = mRegion.GetNumRects ();
00140 
00141   if (pRegionSet == nsnull)                 // Not yet allocated
00142   {
00143     PRUint8* pBuf = new PRUint8 [sizeof (nsRegionRectSet) + NumRects * sizeof (nsRegionRect)];
00144     pRegionSet = NS_REINTERPRET_CAST (nsRegionRectSet*, pBuf);
00145     pRegionSet->mRectsLen = NumRects + 1;
00146   } else                                    // Already allocated in previous call
00147   {
00148     if (NumRects > pRegionSet->mRectsLen)   // passed array is not big enough - reallocate it.
00149     {
00150       delete [] NS_REINTERPRET_CAST (PRUint8*, pRegionSet);
00151       PRUint8* pBuf = new PRUint8 [sizeof (nsRegionRectSet) + NumRects * sizeof (nsRegionRect)];
00152       pRegionSet = NS_REINTERPRET_CAST (nsRegionRectSet*, pBuf);
00153       pRegionSet->mRectsLen = NumRects + 1;
00154     }
00155   }
00156   pRegionSet->mNumRects = NumRects;
00157   *aRects = pRegionSet;
00158 
00159 
00160   nsRegionRectIterator ri (mRegion);
00161   nsRegionRect* pDest = &pRegionSet->mRects [0];
00162   const nsRect* pSrc;
00163 
00164   while ((pSrc = ri.Next ()))
00165   {
00166     pDest->x = pSrc->x;
00167     pDest->y = pSrc->y;
00168     pDest->width  = pSrc->width;
00169     pDest->height = pSrc->height;
00170 
00171     pDest++;
00172   }
00173 
00174   return NS_OK;
00175 }
00176 
00177 NS_IMETHODIMP
00178 nsCairoRegion::FreeRects (nsRegionRectSet *aRects)
00179 {
00180   if (!aRects)
00181     return NS_ERROR_NULL_POINTER;
00182 
00183   delete [] NS_REINTERPRET_CAST (PRUint8*, aRects);
00184   return NS_OK;
00185 }
00186 
00187 NS_IMETHODIMP
00188 nsCairoRegion::GetNativeRegion (void *&aRegion) const
00189 {
00190   aRegion = 0;
00191   return NS_OK;
00192 }
00193 
00194 NS_IMETHODIMP
00195 nsCairoRegion::GetRegionComplexity (nsRegionComplexity &aComplexity) const
00196 {
00197   switch (mRegion.GetNumRects ())
00198   {
00199     case 0:   aComplexity = eRegionComplexity_empty;    break;
00200     case 1:   aComplexity = eRegionComplexity_rect;     break;
00201     default:  aComplexity = eRegionComplexity_complex;  break;
00202   }
00203 
00204   return NS_OK;
00205 }
00206 
00207 NS_IMETHODIMP
00208 nsCairoRegion::GetNumRects (PRUint32 *aRects) const
00209 {
00210   *aRects = mRegion.GetNumRects ();
00211   return NS_OK;
00212 }