root/dwt/graphics/Region.d

Revision 246:fd9c62a2998e, 19.6 kB (checked in by Frank Benoit <benoit@tionex.de>, 6 months ago)

Updater SWT 3.4M7 to 3.4

Line 
1 /*******************************************************************************
2  * Copyright (c) 2000, 2008 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  * Port to the D programming language:
11  *     Frank Benoit <benoit@tionex.de>
12  *******************************************************************************/
13 module dwt.graphics.Region;
14
15
16 import dwt.DWT;
17 import dwt.DWTError;
18 import dwt.DWTException;
19 import dwt.internal.win32.OS;
20
21 import dwt.graphics.Resource;
22 import dwt.graphics.Point;
23 import dwt.graphics.Rectangle;
24 import dwt.graphics.Device;
25
26 import tango.text.convert.Format;
27 import dwt.dwthelper.utils;
28
29 /**
30  * Instances of this class represent areas of an x-y coordinate
31  * system that are aggregates of the areas covered by a number
32  * of polygons.
33  * <p>
34  * Application code must explicitly invoke the <code>Region.dispose()</code>
35  * method to release the operating system resources managed by each instance
36  * when those instances are no longer required.
37  * </p>
38  *
39  * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Example: GraphicsExample</a>
40  * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
41  */
42
43 public final class Region : Resource {
44     alias Resource.init_ init_;
45
46     /**
47      * the OS resource for the region
48      * (Warning: This field is platform dependent)
49      * <p>
50      * <b>IMPORTANT:</b> This field is <em>not</em> part of the DWT
51      * public API. It is marked public only so that it can be shared
52      * within the packages provided by DWT. It is not available on all
53      * platforms and should never be accessed from application code.
54      * </p>
55      */
56     public HRGN handle;
57
58 /**
59  * Constructs a new empty region.
60  *
61  * @exception DWTError <ul>
62  *    <li>ERROR_NO_HANDLES if a handle could not be obtained for region creation</li>
63  * </ul>
64  */
65 public this () {
66     this(null);
67 }
68
69 /**
70  * Constructs a new empty region.
71  * <p>
72  * You must dispose the region when it is no longer required.
73  * </p>
74  *
75  * @param device the device on which to allocate the region
76  *
77  * @exception IllegalArgumentException <ul>
78  *    <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
79  * </ul>
80  * @exception DWTError <ul>
81  *    <li>ERROR_NO_HANDLES if a handle could not be obtained for region creation</li>
82  * </ul>
83  *
84  * @see #dispose
85  *
86  * @since 3.0
87  */
88 public this (Device device) {
89     super(device);
90     handle = OS.CreateRectRgn (0, 0, 0, 0);
91     if (handle is null) DWT.error(DWT.ERROR_NO_HANDLES);
92     init_();
93 }
94
95 /**
96  * Constructs a new region given a handle to the operating
97  * system resources that it should represent.
98  *
99  * @param handle the handle for the result
100  */
101 this(Device device, HRGN handle) {
102     super(device);
103     this.handle = handle;
104 }
105
106 /**
107  * Adds the given polygon to the collection of polygons
108  * the receiver maintains to describe its area.
109  *
110  * @param pointArray points that describe the polygon to merge with the receiver
111  *
112  * @exception IllegalArgumentException <ul>
113  *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
114  * </ul>
115  * @exception DWTException <ul>
116  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
117  * </ul>
118  *
119  * @since 3.0
120 *
121  */
122 public void add (int[] pointArray) {
123     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
124     if (pointArray is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
125     static if (OS.IsWinCE) DWT.error(DWT.ERROR_NOT_IMPLEMENTED);
126     auto polyRgn = OS.CreatePolygonRgn(cast(POINT*)pointArray.ptr, pointArray.length / 2, OS.ALTERNATE);
127     OS.CombineRgn (handle, handle, polyRgn, OS.RGN_OR);
128     OS.DeleteObject (polyRgn);
129 }
130
131 /**
132  * Adds the given rectangle to the collection of polygons
133  * the receiver maintains to describe its area.
134  *
135  * @param rect the rectangle to merge with the receiver
136  *
137  * @exception IllegalArgumentException <ul>
138  *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
139  *    <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or height is negative</li>
140  * </ul>
141  * @exception DWTException <ul>
142  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
143  * </ul>
144  */
145 public void add (Rectangle rect) {
146     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
147     if (rect is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
148     add (rect.x, rect.y, rect.width, rect.height);
149 }
150
151 /**
152  * Adds the given rectangle to the collection of polygons
153  * the receiver maintains to describe its area.
154  *
155  * @param x the x coordinate of the rectangle
156  * @param y the y coordinate of the rectangle
157  * @param width the width coordinate of the rectangle
158  * @param height the height coordinate of the rectangle
159  *
160  * @exception IllegalArgumentException <ul>
161  *    <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or height is negative</li>
162  * </ul>
163  * @exception DWTException <ul>
164  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
165  * </ul>
166  *
167  * @since 3.1
168  */
169 public void add (int x, int y, int width, int height) {
170     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
171     if (width < 0 || height < 0) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
172     auto rectRgn = OS.CreateRectRgn (x, y, x + width, y + height);
173     OS.CombineRgn (handle, handle, rectRgn, OS.RGN_OR);
174     OS.DeleteObject (rectRgn);
175 }
176
177 /**
178  * Adds all of the polygons which make up the area covered
179  * by the argument to the collection of polygons the receiver
180  * maintains to describe its area.
181  *
182  * @param region the region to merge
183  *
184  * @exception IllegalArgumentException <ul>
185  *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
186  *    <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
187  * </ul>
188  * @exception DWTException <ul>
189  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
190  * </ul>
191  */
192 public void add (Region region) {
193     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
194     if (region is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
195     if (region.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
196     OS.CombineRgn (handle, handle, region.handle, OS.RGN_OR);
197 }
198
199 /**
200  * Returns <code>true</code> if the point specified by the
201  * arguments is inside the area specified by the receiver,
202  * and <code>false</code> otherwise.
203  *
204  * @param x the x coordinate of the point to test for containment
205  * @param y the y coordinate of the point to test for containment
206  * @return <code>true</code> if the region contains the point and <code>false</code> otherwise
207  *
208  * @exception DWTException <ul>
209  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
210  * </ul>
211  */
212 public bool contains (int x, int y) {
213     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
214     return cast(bool) OS.PtInRegion (handle, x, y);
215 }
216
217 /**
218  * Returns <code>true</code> if the given point is inside the
219  * area specified by the receiver, and <code>false</code>
220  * otherwise.
221  *
222  * @param pt the point to test for containment
223  * @return <code>true</code> if the region contains the point and <code>false</code> otherwise
224  *
225  * @exception IllegalArgumentException <ul>
226  *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
227  * </ul>
228  * @exception DWTException <ul>
229  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
230  * </ul>
231  */
232 public bool contains (Point pt) {
233     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
234     if (pt is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
235     return contains(pt.x, pt.y);
236 }
237
238 void destroy () {
239     OS.DeleteObject(handle);
240     handle = null;
241 }
242
243 /**
244  * Compares the argument to the receiver, and returns true
245  * if they represent the <em>same</em> object using a class
246  * specific comparison.
247  *
248  * @param object the object to compare with this object
249  * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise
250  *
251  * @see #hashCode
252  */
253 override public int opEquals (Object object) {
254     if (this is object) return true;
255     if (!(cast(Region)object)) return false;
256     Region rgn = cast(Region)object;
257     return handle is rgn.handle;
258 }
259
260 /**
261  * Returns a rectangle which represents the rectangular
262  * union of the collection of polygons the receiver
263  * maintains to describe its area.
264  *
265  * @return a bounding rectangle for the region
266  *
267  * @exception DWTException <ul>
268  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
269  * </ul>
270  *
271  * @see Rectangle#union
272  */
273 public Rectangle getBounds() {
274     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
275     RECT rect;
276     OS.GetRgnBox(handle, &rect);
277     return new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
278 }
279
280 /**
281  * Returns an integer hash code for the receiver. Any two
282  * objects that return <code>true</code> when passed to
283  * <code>equals</code> must return the same value for this
284  * method.
285  *
286  * @return the receiver's hash
287  *
288  * @see #equals
289  */
290 override public hash_t toHash () {
291     return cast(hash_t)handle;
292 }
293
294 /**
295  * Intersects the given rectangle to the collection of polygons
296  * the receiver maintains to describe its area.
297  *
298  * @param rect the rectangle to intersect with the receiver
299  *
300  * @exception IllegalArgumentException <ul>
301  *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
302  *    <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or height is negative</li>
303  * </ul>
304  * @exception DWTException <ul>
305  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
306  * </ul>
307  *
308  * @since 3.0
309  */
310 public void intersect (Rectangle rect) {
311     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
312     if (rect is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
313     intersect (rect.x, rect.y, rect.width, rect.height);
314 }
315
316 /**
317  * Intersects the given rectangle to the collection of polygons
318  * the receiver maintains to describe its area.
319  *
320  * @param x the x coordinate of the rectangle
321  * @param y the y coordinate of the rectangle
322  * @param width the width coordinate of the rectangle
323  * @param height the height coordinate of the rectangle
324  *
325  * @exception IllegalArgumentException <ul>
326  *    <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or height is negative</li>
327  * </ul>
328  * @exception DWTException <ul>
329  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
330  * </ul>
331  *
332  * @since 3.1
333  */
334 public void intersect (int x, int y, int width, int height) {
335     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
336     if (width < 0 || height < 0) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
337     auto rectRgn = OS.CreateRectRgn (x, y, x + width, y + height);
338     OS.CombineRgn (handle, handle, rectRgn, OS.RGN_AND);
339     OS.DeleteObject (rectRgn);
340 }
341
342 /**
343  * Intersects all of the polygons which make up the area covered
344  * by the argument to the collection of polygons the receiver
345  * maintains to describe its area.
346  *
347  * @param region the region to intersect
348  *
349  * @exception IllegalArgumentException <ul>
350  *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
351  *    <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
352  * </ul>
353  * @exception DWTException <ul>
354  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
355  * </ul>
356  *
357  * @since 3.0
358  */
359 public void intersect (Region region) {
360     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
361     if (region is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
362     if (region.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
363     OS.CombineRgn (handle, handle, region.handle, OS.RGN_AND);
364 }
365
366 /**
367  * Returns <code>true</code> if the rectangle described by the
368  * arguments intersects with any of the polygons the receiver
369  * maintains to describe its area, and <code>false</code> otherwise.
370  *
371  * @param x the x coordinate of the origin of the rectangle
372  * @param y the y coordinate of the origin of the rectangle
373  * @param width the width of the rectangle
374  * @param height the height of the rectangle
375  * @return <code>true</code> if the rectangle intersects with the receiver, and <code>false</code> otherwise
376  *
377  * @exception DWTException <ul>
378  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
379  * </ul>
380  *
381  * @see Rectangle#intersects(Rectangle)
382  */
383 public bool intersects (int x, int y, int width, int height) {
384     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
385     RECT r;
386     OS.SetRect (&r, x, y, x + width, y + height);
387     return cast(bool) OS.RectInRegion (handle, &r);
388 }
389
390 /**
391  * Returns <code>true</code> if the given rectangle intersects
392  * with any of the polygons the receiver maintains to describe
393  * its area and <code>false</code> otherwise.
394  *
395  * @param rect the rectangle to test for intersection
396  * @return <code>true</code> if the rectangle intersects with the receiver, and <code>false</code> otherwise
397  *
398  * @exception IllegalArgumentException <ul>
399  *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
400  * </ul>
401  * @exception DWTException <ul>
402  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
403  * </ul>
404  *
405  * @see Rectangle#intersects(Rectangle)
406  */
407 public bool intersects (Rectangle rect) {
408     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
409     if (rect is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
410     return intersects(rect.x, rect.y, rect.width, rect.height);
411 }
412
413 /**
414  * Returns <code>true</code> if the region has been disposed,
415  * and <code>false</code> otherwise.
416  * <p>
417  * This method gets the dispose state for the region.
418  * When a region has been disposed, it is an error to
419  * invoke any other method using the region.
420  *
421  * @return <code>true</code> when the region is disposed, and <code>false</code> otherwise
422  */
423 override public bool isDisposed() {
424     return handle is null;
425 }
426
427 /**
428  * Returns <code>true</code> if the receiver does not cover any
429  * area in the (x, y) coordinate plane, and <code>false</code> if
430  * the receiver does cover some area in the plane.
431  *
432  * @return <code>true</code> if the receiver is empty, and <code>false</code> otherwise
433  *
434  * @exception DWTException <ul>
435  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
436  * </ul>
437  */
438 public bool isEmpty () {
439     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
440     RECT rect;
441     auto result = OS.GetRgnBox (handle, &rect);
442     if (result is OS.NULLREGION) return true;
443     return ((rect.right - rect.left) <= 0) || ((rect.bottom - rect.top) <= 0);
444 }
445
446 /**
447  * Subtracts the given polygon from the collection of polygons
448  * the receiver maintains to describe its area.
449  *
450  * @param pointArray points that describe the polygon to merge with the receiver
451  *
452  * @exception IllegalArgumentException <ul>
453  *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
454  * </ul>
455  * @exception DWTException <ul>
456  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
457  * </ul>
458  *
459  * @since 3.0
460  */
461 public void subtract (int[] pointArray) {
462     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
463     if (pointArray is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
464     static if (OS.IsWinCE) DWT.error(DWT.ERROR_NOT_IMPLEMENTED);
465     auto polyRgn = OS.CreatePolygonRgn(cast(POINT*)pointArray.ptr, pointArray.length / 2, OS.ALTERNATE);
466     OS.CombineRgn (handle, handle, polyRgn, OS.RGN_DIFF);
467     OS.DeleteObject (polyRgn);
468 }
469
470 /**
471  * Subtracts the given rectangle from the collection of polygons
472  * the receiver maintains to describe its area.
473  *
474  * @param rect the rectangle to subtract from the receiver
475  *
476  * @exception IllegalArgumentException <ul>
477  *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
478  *    <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or height is negative</li>
479  * </ul>
480  * @exception DWTException <ul>
481  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
482  * </ul>
483  *
484  * @since 3.0
485  */
486 public void subtract (Rectangle rect) {
487     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
488     if (rect is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
489     subtract (rect.x, rect.y, rect.width, rect.height);
490 }
491
492 /**
493  * Subtracts the given rectangle from the collection of polygons
494  * the receiver maintains to describe its area.
495  *
496  * @param x the x coordinate of the rectangle
497  * @param y the y coordinate of the rectangle
498  * @param width the width coordinate of the rectangle
499  * @param height the height coordinate of the rectangle
500  *
501  * @exception IllegalArgumentException <ul>
502  *    <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or height is negative</li>
503  * </ul>
504  * @exception DWTException <ul>
505  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
506  * </ul>
507  *
508  * @since 3.1
509  */
510 public void subtract (int x, int y, int width, int height) {
511     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
512     if (width < 0 || height < 0) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
513     auto rectRgn = OS.CreateRectRgn (x, y, x + width, y + height);
514     OS.CombineRgn (handle, handle, rectRgn, OS.RGN_DIFF);
515     OS.DeleteObject (rectRgn);
516 }
517
518 /**
519  * Subtracts all of the polygons which make up the area covered
520  * by the argument from the collection of polygons the receiver
521  * maintains to describe its area.
522  *
523  * @param region the region to subtract
524  *
525  * @exception IllegalArgumentException <ul>
526  *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
527  *    <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
528  * </ul>
529  * @exception DWTException <ul>
530  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
531  * </ul>
532  *
533  * @since 3.0
534  */
535 public void subtract (Region region) {
536     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
537     if (region is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
538     if (region.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
539     OS.CombineRgn (handle, handle, region.handle, OS.RGN_DIFF);
540 }
541
542 /**
543  * Translate all of the polygons the receiver maintains to describe
544  * its area by the specified point.
545  *
546  * @param x the x coordinate of the point to translate
547  * @param y the y coordinate of the point to translate
548  *
549  * @exception DWTException <ul>
550  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
551  * </ul>
552  *
553  * @since 3.1
554  */
555 public void translate (int x, int y) {
556     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
557     OS.OffsetRgn (handle, x, y);
558 }
559
560 /**
561  * Translate all of the polygons the receiver maintains to describe
562  * its area by the specified point.
563  *
564  * @param pt the point to translate
565  *
566  * @exception IllegalArgumentException <ul>
567  *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
568  * </ul>
569  * @exception DWTException <ul>
570  *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
571  * </ul>
572  *
573  * @since 3.1
574  */
575 public void translate (Point pt) {
576     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
577     if (pt is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
578     translate (pt.x, pt.y);
579 }
580
581 /**
582  * Returns a string containing a concise, human-readable
583  * description of the receiver.
584  *
585  * @return a string representation of the receiver
586  */
587 override public String toString () {
588     if (isDisposed()) return "Region {*DISPOSED*}";
589     return Format( "Region {{{}}", handle );
590 }
591
592 /**
593  * Invokes platform specific functionality to allocate a new region.
594  * <p>
595  * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
596  * API for <code>Region</code>. It is marked public only so that it
597  * can be shared within the packages provided by DWT. It is not
598  * available on all platforms, and should never be called from
599  * application code.
600  * </p>
601  *
602  * @param device the device on which to allocate the region
603  * @param handle the handle for the region
604  * @return a new region object containing the specified device and handle
605  */
606 public static Region win32_new(Device device, HRGN handle) {
607     return new Region(device, handle);
608 }
609
610 }
Note: See TracBrowser for help on using the browser.