|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 * |
|
3 * This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #include "nsScriptableRegion.h" |
|
8 #include <stdint.h> // for uint32_t |
|
9 #include <sys/types.h> // for int32_t |
|
10 #include "js/RootingAPI.h" // for Rooted |
|
11 #include "js/Value.h" // for INT_TO_JSVAL, etc |
|
12 #include "jsapi.h" // for JS_DefineElement, etc |
|
13 #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2 |
|
14 #include "nsError.h" // for NS_OK, NS_ERROR_FAILURE, etc |
|
15 #include "nsID.h" |
|
16 #include "nsRect.h" // for nsIntRect |
|
17 #include "nscore.h" // for NS_IMETHODIMP |
|
18 |
|
19 class JSObject; |
|
20 struct JSContext; |
|
21 |
|
22 nsScriptableRegion::nsScriptableRegion() |
|
23 { |
|
24 } |
|
25 |
|
26 NS_IMPL_ISUPPORTS(nsScriptableRegion, nsIScriptableRegion) |
|
27 |
|
28 NS_IMETHODIMP nsScriptableRegion::Init() |
|
29 { |
|
30 return NS_OK; |
|
31 } |
|
32 |
|
33 NS_IMETHODIMP nsScriptableRegion::SetToRegion(nsIScriptableRegion *aRegion) |
|
34 { |
|
35 aRegion->GetRegion(&mRegion); |
|
36 return NS_OK; |
|
37 } |
|
38 |
|
39 NS_IMETHODIMP nsScriptableRegion::SetToRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight) |
|
40 { |
|
41 mRegion = nsIntRect(aX, aY, aWidth, aHeight); |
|
42 return NS_OK; |
|
43 } |
|
44 |
|
45 NS_IMETHODIMP nsScriptableRegion::IntersectRegion(nsIScriptableRegion *aRegion) |
|
46 { |
|
47 nsIntRegion region; |
|
48 aRegion->GetRegion(®ion); |
|
49 mRegion.And(mRegion, region); |
|
50 return NS_OK; |
|
51 } |
|
52 |
|
53 NS_IMETHODIMP nsScriptableRegion::IntersectRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight) |
|
54 { |
|
55 mRegion.And(mRegion, nsIntRect(aX, aY, aWidth, aHeight)); |
|
56 return NS_OK; |
|
57 } |
|
58 |
|
59 NS_IMETHODIMP nsScriptableRegion::UnionRegion(nsIScriptableRegion *aRegion) |
|
60 { |
|
61 nsIntRegion region; |
|
62 aRegion->GetRegion(®ion); |
|
63 mRegion.Or(mRegion, region); |
|
64 return NS_OK; |
|
65 } |
|
66 |
|
67 NS_IMETHODIMP nsScriptableRegion::UnionRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight) |
|
68 { |
|
69 mRegion.Or(mRegion, nsIntRect(aX, aY, aWidth, aHeight)); |
|
70 return NS_OK; |
|
71 } |
|
72 |
|
73 NS_IMETHODIMP nsScriptableRegion::SubtractRegion(nsIScriptableRegion *aRegion) |
|
74 { |
|
75 nsIntRegion region; |
|
76 aRegion->GetRegion(®ion); |
|
77 mRegion.Sub(mRegion, region); |
|
78 return NS_OK; |
|
79 } |
|
80 |
|
81 NS_IMETHODIMP nsScriptableRegion::SubtractRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight) |
|
82 { |
|
83 mRegion.Sub(mRegion, nsIntRect(aX, aY, aWidth, aHeight)); |
|
84 return NS_OK; |
|
85 } |
|
86 |
|
87 NS_IMETHODIMP nsScriptableRegion::IsEmpty(bool *isEmpty) |
|
88 { |
|
89 *isEmpty = mRegion.IsEmpty(); |
|
90 return NS_OK; |
|
91 } |
|
92 |
|
93 NS_IMETHODIMP nsScriptableRegion::IsEqualRegion(nsIScriptableRegion *aRegion, bool *isEqual) |
|
94 { |
|
95 nsIntRegion region; |
|
96 aRegion->GetRegion(®ion); |
|
97 *isEqual = mRegion.IsEqual(region); |
|
98 return NS_OK; |
|
99 } |
|
100 |
|
101 NS_IMETHODIMP nsScriptableRegion::GetBoundingBox(int32_t *aX, int32_t *aY, int32_t *aWidth, int32_t *aHeight) |
|
102 { |
|
103 nsIntRect boundRect = mRegion.GetBounds(); |
|
104 *aX = boundRect.x; |
|
105 *aY = boundRect.y; |
|
106 *aWidth = boundRect.width; |
|
107 *aHeight = boundRect.height; |
|
108 return NS_OK; |
|
109 } |
|
110 |
|
111 NS_IMETHODIMP nsScriptableRegion::Offset(int32_t aXOffset, int32_t aYOffset) |
|
112 { |
|
113 mRegion.MoveBy(aXOffset, aYOffset); |
|
114 return NS_OK; |
|
115 } |
|
116 |
|
117 NS_IMETHODIMP nsScriptableRegion::ContainsRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight, bool *containsRect) |
|
118 { |
|
119 *containsRect = mRegion.Contains(nsIntRect(aX, aY, aWidth, aHeight)); |
|
120 return NS_OK; |
|
121 } |
|
122 |
|
123 |
|
124 NS_IMETHODIMP nsScriptableRegion::GetRegion(nsIntRegion* outRgn) |
|
125 { |
|
126 *outRgn = mRegion; |
|
127 return NS_OK; |
|
128 } |
|
129 |
|
130 NS_IMETHODIMP nsScriptableRegion::GetRects(JSContext* aCx, JS::MutableHandle<JS::Value> aRects) |
|
131 { |
|
132 uint32_t numRects = mRegion.GetNumRects(); |
|
133 |
|
134 if (!numRects) { |
|
135 aRects.setNull(); |
|
136 return NS_OK; |
|
137 } |
|
138 |
|
139 JS::Rooted<JSObject*> destArray(aCx, JS_NewArrayObject(aCx, numRects * 4)); |
|
140 if (!destArray) { |
|
141 return NS_ERROR_OUT_OF_MEMORY; |
|
142 } |
|
143 |
|
144 aRects.setObject(*destArray); |
|
145 |
|
146 uint32_t n = 0; |
|
147 nsIntRegionRectIterator iter(mRegion); |
|
148 const nsIntRect *rect; |
|
149 |
|
150 while ((rect = iter.Next())) { |
|
151 if (!JS_DefineElement(aCx, destArray, n, INT_TO_JSVAL(rect->x), nullptr, nullptr, JSPROP_ENUMERATE) || |
|
152 !JS_DefineElement(aCx, destArray, n + 1, INT_TO_JSVAL(rect->y), nullptr, nullptr, JSPROP_ENUMERATE) || |
|
153 !JS_DefineElement(aCx, destArray, n + 2, INT_TO_JSVAL(rect->width), nullptr, nullptr, JSPROP_ENUMERATE) || |
|
154 !JS_DefineElement(aCx, destArray, n + 3, INT_TO_JSVAL(rect->height), nullptr, nullptr, JSPROP_ENUMERATE)) { |
|
155 return NS_ERROR_FAILURE; |
|
156 } |
|
157 n += 4; |
|
158 } |
|
159 |
|
160 return NS_OK; |
|
161 } |