Bug 477708 - expose nsIRegion::getrects() to scripts r=vlad
authorTaras Glek <tglek@mozilla.com>
Wed, 18 Mar 2009 11:42:07 -0700
changeset 26317 cb3129b2d9f2da721a6640fa2c3e8111638aefd8
parent 26316 5917a57686c3e07eeda7a793eca1b0e82ff1d8bf
child 26318 849a7932884bdd3460fdbc79ef0a9c8d5dfeedce
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvlad
bugs477708
milestone1.9.2a1pre
Bug 477708 - expose nsIRegion::getrects() to scripts r=vlad
gfx/idl/nsIScriptableRegion.idl
gfx/src/Makefile.in
gfx/src/nsScriptableRegion.cpp
gfx/src/nsScriptableRegion.h
--- a/gfx/idl/nsIScriptableRegion.idl
+++ b/gfx/idl/nsIScriptableRegion.idl
@@ -41,17 +41,17 @@
 
 %{C++
 class nsIRegion;
 %}
 
 [ptr] native nsIRegion(nsIRegion);
 
 
-[scriptable, uuid(82d8f400-5bde-11d3-b033-b27a62766bbc)]
+[scriptable, uuid(4d179656-a5bd-42a6-a937-c81f820dcf2f)]
 interface nsIScriptableRegion : nsISupports
 {
   void init ( ) ;
 
   /**
   * copy operator equivalent that takes another region
   *
   * @param      region to copy
@@ -183,16 +183,23 @@ interface nsIScriptableRegion : nsISuppo
   * @param  xoffset  pixel offset in x
   * @param  yoffset  pixel offset in y
   * @return          void
   *
   **/
   void offset ( in long aXOffset, in long aYOffset ) ;
 
   /**
+   * @return null if there are no rects,
+   * @return flat array of rects,ie [x1,y1,width1,height1,x2...].
+   * The result will contain bogus data if values don't fit in 31 bit
+   **/
+  void getRects();
+
+  /**
   * does the region intersect the rectangle?
   *
   * @param      rect to check for containment
   * @return     true if the region intersects the rect
   *
   **/
 
   boolean containsRect ( in long aX, in long aY, in long aWidth, in long aHeight ) ;
--- a/gfx/src/Makefile.in
+++ b/gfx/src/Makefile.in
@@ -50,16 +50,18 @@ LIBXUL_LIBRARY = 1
 
 REQUIRES	= xpcom \
 		  string \
 		  widget \
 		  locale \
 		  view \
 		  unicharutil \
 		  thebes \
+		  js \
+		  xpconnect \
 		  $(NULL)
 
 DIRS        = shared thebes
 
 ifdef MOZ_ENABLE_POSTSCRIPT
 DIRS        += psshared
 endif
 
@@ -76,16 +78,17 @@ CPPSRCS = \
 ifeq (,$(filter windows,$(MOZ_WIDGET_TOOLKIT)))
 REQUIRES += uconv
 endif
 
 EXTRA_DSO_LDOPTS = \
         $(DEPTH)/modules/libutil/src/$(LIB_PREFIX)mozutil_s.$(LIB_SUFFIX) \
         $(MOZ_UNICHARUTIL_LIBS) \
         $(MOZ_COMPONENT_LIBS) \
+        $(MOZ_JS_LIBS) \
         $(NULL)
 
 ifneq (,$(filter cocoa,$(MOZ_WIDGET_TOOLKIT)))
 EXTRA_DSO_LDOPTS += \
         $(TK_LIBS) \
         $(NULL)
 endif
 
--- a/gfx/src/nsScriptableRegion.cpp
+++ b/gfx/src/nsScriptableRegion.cpp
@@ -17,44 +17,50 @@
  *
  * The Initial Developer of the Original Code is
  * Netscape Communications Corp.
  * Portions created by the Initial Developer are Copyright (C) 1999
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Patrick Beard
+ *   Taras Glek
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either of the GNU General Public License Version 2 or later (the "GPL"),
  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsScriptableRegion.h"
-#include "nsIRegion.h"
 #include "nsCOMPtr.h"
+#include "nsIXPConnect.h"
+#include "nsServiceManagerUtils.h"
+#include "jsapi.h"
 
-nsScriptableRegion::nsScriptableRegion(nsIRegion* region) : mRegion(nsnull)
+nsScriptableRegion::nsScriptableRegion(nsIRegion* region) : mRegion(nsnull), mRectSet(nsnull)
 {
 	mRegion = region;
 	NS_IF_ADDREF(mRegion);
 }
 
 nsScriptableRegion::~nsScriptableRegion()
 {
-	NS_IF_RELEASE(mRegion);
+  if (mRegion) {
+    mRegion->FreeRects(mRectSet);
+    NS_RELEASE(mRegion);
+  }
 }
 
 NS_IMPL_ISUPPORTS1(nsScriptableRegion, nsIScriptableRegion)
 
 NS_IMETHODIMP nsScriptableRegion::Init()
 {
 	return mRegion->Init();
 }
@@ -144,8 +150,55 @@ NS_IMETHODIMP nsScriptableRegion::Contai
 
 
 NS_IMETHODIMP nsScriptableRegion::GetRegion(nsIRegion** outRgn)
 {
   *outRgn = mRegion;
   NS_IF_ADDREF(*outRgn);
   return NS_OK;
 }
+
+NS_IMETHODIMP nsScriptableRegion::GetRects() {
+  nsAXPCNativeCallContext *ncc = nsnull;
+  nsIXPConnect *xpConnect;
+  nsresult rv = CallGetService(nsIXPConnect::GetCID(), &xpConnect);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = xpConnect->GetCurrentNativeCallContext(&ncc);
+  NS_ENSURE_SUCCESS(rv, rv);
+  
+  if (!ncc)
+    return NS_ERROR_FAILURE;
+  
+  jsval *retvalPtr;
+  ncc->GetRetValPtr(&retvalPtr);
+  
+  rv = mRegion->GetRects(&mRectSet);
+  NS_ENSURE_SUCCESS(rv, rv);
+  
+  if (!mRectSet->mNumRects) {
+    *retvalPtr = JSVAL_NULL;
+    ncc->SetReturnValueWasSet(PR_TRUE);
+    return NS_OK;
+  }
+
+  JSContext *cx = nsnull;
+  
+  rv = ncc->GetJSContext(&cx);
+  NS_ENSURE_SUCCESS(rv, rv);
+  
+  JSObject *destArray = JS_NewArrayObject(cx, mRectSet->mNumRects*4, NULL);
+  *retvalPtr = OBJECT_TO_JSVAL(destArray);
+  ncc->SetReturnValueWasSet(PR_TRUE);
+  
+  for(PRUint32 i = 0; i < mRectSet->mNumRects; i++) {
+    nsRegionRect &rect = mRectSet->mRects[i];
+    int n = i*4;
+    // This will contain bogus data if values don't fit in 31 bit
+    JS_DefineElement(cx, destArray, n, INT_TO_JSVAL(rect.x), NULL, NULL, JSPROP_ENUMERATE);
+    JS_DefineElement(cx, destArray, n+1, INT_TO_JSVAL(rect.y), NULL, NULL, JSPROP_ENUMERATE);
+    JS_DefineElement(cx, destArray, n+2, INT_TO_JSVAL(rect.width), NULL, NULL, JSPROP_ENUMERATE);
+    JS_DefineElement(cx, destArray, n+3, INT_TO_JSVAL(rect.height), NULL, NULL, JSPROP_ENUMERATE);
+  }
+
+  NS_ENSURE_SUCCESS(rv, rv);
+  return NS_OK;
+}
--- a/gfx/src/nsScriptableRegion.h
+++ b/gfx/src/nsScriptableRegion.h
@@ -34,16 +34,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIScriptableRegion.h"
 #include "gfxCore.h"
+#include "nsIRegion.h"
 
 class nsIRegion;
 
 /**
  * An adapter class for the unscriptable nsIRegion interface.
  */
 class NS_GFX nsScriptableRegion : public nsIScriptableRegion {
 public:
@@ -51,9 +52,10 @@ public:
 	virtual ~nsScriptableRegion();
 	
 	NS_DECL_ISUPPORTS
 
 	NS_DECL_NSISCRIPTABLEREGION
 
 private:
 	nsIRegion* mRegion;
+	nsRegionRectSet *mRectSet;
 };