001: /*******************************************************************************
002: * Copyright (c) 2000, 2005 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.swt.graphics;
011:
012: import org.eclipse.swt.internal.carbon.*;
013: import org.eclipse.swt.*;
014:
015: /**
016: * Instances of this class represent areas of an x-y coordinate
017: * system that are aggregates of the areas covered by a number
018: * of polygons.
019: * <p>
020: * Application code must explicitly invoke the <code>Region.dispose()</code>
021: * method to release the operating system resources managed by each instance
022: * when those instances are no longer required.
023: * </p>
024: */
025: public final class Region extends Resource {
026: /**
027: * the OS resource for the region
028: * (Warning: This field is platform dependent)
029: * <p>
030: * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
031: * public API. It is marked public only so that it can be shared
032: * within the packages provided by SWT. It is not available on all
033: * platforms and should never be accessed from application code.
034: * </p>
035: */
036: public int handle;
037:
038: /**
039: * Constructs a new empty region.
040: *
041: * @exception SWTError <ul>
042: * <li>ERROR_NO_HANDLES if a handle could not be obtained for region creation</li>
043: * </ul>
044: */
045: public Region() {
046: this (null);
047: }
048:
049: /**
050: * Constructs a new empty region.
051: * <p>
052: * You must dispose the region when it is no longer required.
053: * </p>
054: *
055: * @param device the device on which to allocate the region
056: *
057: * @exception IllegalArgumentException <ul>
058: * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
059: * </ul>
060: * @exception SWTError <ul>
061: * <li>ERROR_NO_HANDLES if a handle could not be obtained for region creation</li>
062: * </ul>
063: *
064: * @see #dispose
065: *
066: * @since 3.0
067: */
068: public Region(Device device) {
069: if (device == null)
070: device = Device.getDevice();
071: if (device == null)
072: SWT.error(SWT.ERROR_NULL_ARGUMENT);
073: this .device = device;
074: handle = OS.NewRgn();
075: if (handle == 0)
076: SWT.error(SWT.ERROR_NO_HANDLES);
077: }
078:
079: Region(Device device, int handle) {
080: this .device = device;
081: this .handle = handle;
082: }
083:
084: /**
085: * Adds the given polygon to the collection of polygons
086: * the receiver maintains to describe its area.
087: *
088: * @param pointArray points that describe the polygon to merge with the receiver
089: *
090: * @exception IllegalArgumentException <ul>
091: * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
092: * </ul>
093: * @exception SWTException <ul>
094: * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
095: * </ul>
096: *
097: * @since 3.0
098: *
099: */
100: public void add(int[] pointArray) {
101: if (isDisposed())
102: SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
103: if (pointArray == null)
104: SWT.error(SWT.ERROR_NULL_ARGUMENT);
105: if (pointArray.length < 2)
106: return;
107: int polyRgn = OS.NewRgn();
108: OS.OpenRgn();
109: OS.MoveTo((short) pointArray[0], (short) pointArray[1]);
110: for (int i = 1; i < pointArray.length / 2; i++) {
111: OS.LineTo((short) pointArray[2 * i],
112: (short) pointArray[2 * i + 1]);
113: }
114: OS.LineTo((short) pointArray[0], (short) pointArray[1]);
115: OS.CloseRgn(polyRgn);
116: OS.UnionRgn(handle, polyRgn, handle);
117: OS.DisposeRgn(polyRgn);
118: }
119:
120: /**
121: * Adds the given rectangle to the collection of polygons
122: * the receiver maintains to describe its area.
123: *
124: * @param rect the rectangle to merge with the receiver
125: *
126: * @exception IllegalArgumentException <ul>
127: * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
128: * <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or height is negative</li>
129: * </ul>
130: * @exception SWTException <ul>
131: * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
132: * </ul>
133: */
134: public void add(Rectangle rect) {
135: if (isDisposed())
136: SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
137: if (rect == null)
138: SWT.error(SWT.ERROR_NULL_ARGUMENT);
139: if (rect.width < 0 || rect.height < 0)
140: SWT.error(SWT.ERROR_INVALID_ARGUMENT);
141: add(rect.x, rect.y, rect.width, rect.height);
142: }
143:
144: /**
145: * Adds the given rectangle to the collection of polygons
146: * the receiver maintains to describe its area.
147: *
148: * @param x the x coordinate of the rectangle
149: * @param y the y coordinate of the rectangle
150: * @param width the width coordinate of the rectangle
151: * @param height the height coordinate of the rectangle
152: *
153: * @exception IllegalArgumentException <ul>
154: * <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or height is negative</li>
155: * </ul>
156: * @exception SWTException <ul>
157: * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
158: * </ul>
159: *
160: * @since 3.1
161: */
162: public void add(int x, int y, int width, int height) {
163: if (isDisposed())
164: SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
165: if (width < 0 || height < 0)
166: SWT.error(SWT.ERROR_INVALID_ARGUMENT);
167: int rectRgn = OS.NewRgn();
168: Rect r = new Rect();
169: OS.SetRect(r, (short) x, (short) y, (short) (x + width),
170: (short) (y + height));
171: OS.RectRgn(rectRgn, r);
172: OS.UnionRgn(handle, rectRgn, handle);
173: OS.DisposeRgn(rectRgn);
174: }
175:
176: /**
177: * Adds all of the polygons which make up the area covered
178: * by the argument to the collection of polygons the receiver
179: * maintains to describe its area.
180: *
181: * @param region the region to merge
182: *
183: * @exception IllegalArgumentException <ul>
184: * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
185: * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
186: * </ul>
187: * @exception SWTException <ul>
188: * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
189: * </ul>
190: */
191: public void add(Region region) {
192: if (isDisposed())
193: SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
194: if (region == null)
195: SWT.error(SWT.ERROR_NULL_ARGUMENT);
196: if (region.isDisposed())
197: SWT.error(SWT.ERROR_INVALID_ARGUMENT);
198: OS.UnionRgn(handle, region.handle, handle);
199: }
200:
201: /**
202: * Returns <code>true</code> if the point specified by the
203: * arguments is inside the area specified by the receiver,
204: * and <code>false</code> otherwise.
205: *
206: * @param x the x coordinate of the point to test for containment
207: * @param y the y coordinate of the point to test for containment
208: * @return <code>true</code> if the region contains the point and <code>false</code> otherwise
209: *
210: * @exception SWTException <ul>
211: * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
212: * </ul>
213: */
214: public boolean contains(int x, int y) {
215: if (isDisposed())
216: SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
217: org.eclipse.swt.internal.carbon.Point point = new org.eclipse.swt.internal.carbon.Point();
218: OS.SetPt(point, (short) x, (short) y);
219: return OS.PtInRgn(point, handle);
220: }
221:
222: /**
223: * Returns <code>true</code> if the given point is inside the
224: * area specified by the receiver, and <code>false</code>
225: * otherwise.
226: *
227: * @param pt the point to test for containment
228: * @return <code>true</code> if the region contains the point and <code>false</code> otherwise
229: *
230: * @exception IllegalArgumentException <ul>
231: * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
232: * </ul>
233: * @exception SWTException <ul>
234: * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
235: * </ul>
236: */
237: public boolean contains(Point pt) {
238: if (pt == null)
239: SWT.error(SWT.ERROR_NULL_ARGUMENT);
240: return contains(pt.x, pt.y);
241: }
242:
243: /**
244: * Disposes of the operating system resources associated with
245: * the region. Applications must dispose of all regions which
246: * they allocate.
247: */
248: public void dispose() {
249: if (handle == 0)
250: return;
251: OS.DisposeRgn(handle);
252: handle = 0;
253: device = null;
254: }
255:
256: /**
257: * Compares the argument to the receiver, and returns true
258: * if they represent the <em>same</em> object using a class
259: * specific comparison.
260: *
261: * @param object the object to compare with this object
262: * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise
263: *
264: * @see #hashCode
265: */
266: public boolean equals(Object object) {
267: if (this == object)
268: return true;
269: if (!(object instanceof Region))
270: return false;
271: Region region = (Region) object;
272: return handle == region.handle;
273: }
274:
275: /**
276: * Returns a rectangle which represents the rectangular
277: * union of the collection of polygons the receiver
278: * maintains to describe its area.
279: *
280: * @return a bounding rectangle for the region
281: *
282: * @exception SWTException <ul>
283: * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
284: * </ul>
285: *
286: * @see Rectangle#union
287: */
288: public Rectangle getBounds() {
289: if (isDisposed())
290: SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
291: Rect bounds = new Rect();
292: OS.GetRegionBounds(handle, bounds);
293: int width = bounds.right - bounds.left;
294: int height = bounds.bottom - bounds.top;
295: return new Rectangle(bounds.left, bounds.top, width, height);
296: }
297:
298: public static Region carbon_new(Device device, int handle) {
299: return new Region(device, handle);
300: }
301:
302: /**
303: * Returns an integer hash code for the receiver. Any two
304: * objects that return <code>true</code> when passed to
305: * <code>equals</code> must return the same value for this
306: * method.
307: *
308: * @return the receiver's hash
309: *
310: * @see #equals
311: */
312: public int hashCode() {
313: return handle;
314: }
315:
316: /**
317: * Intersects the given rectangle to the collection of polygons
318: * the receiver maintains to describe its area.
319: *
320: * @param rect the rectangle to intersect with the receiver
321: *
322: * @exception IllegalArgumentException <ul>
323: * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
324: * <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or height is negative</li>
325: * </ul>
326: * @exception SWTException <ul>
327: * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
328: * </ul>
329: *
330: * @since 3.0
331: */
332: public void intersect(Rectangle rect) {
333: if (isDisposed())
334: SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
335: if (rect == null)
336: SWT.error(SWT.ERROR_NULL_ARGUMENT);
337: intersect(rect.x, rect.y, rect.width, rect.height);
338: }
339:
340: /**
341: * Intersects the given rectangle to the collection of polygons
342: * the receiver maintains to describe its area.
343: *
344: * @param x the x coordinate of the rectangle
345: * @param y the y coordinate of the rectangle
346: * @param width the width coordinate of the rectangle
347: * @param height the height coordinate of the rectangle
348: *
349: * @exception IllegalArgumentException <ul>
350: * <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or height is negative</li>
351: * </ul>
352: * @exception SWTException <ul>
353: * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
354: * </ul>
355: *
356: * @since 3.1
357: */
358: public void intersect(int x, int y, int width, int height) {
359: if (isDisposed())
360: SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
361: if (width < 0 || height < 0)
362: SWT.error(SWT.ERROR_INVALID_ARGUMENT);
363: int rectRgn = OS.NewRgn();
364: Rect r = new Rect();
365: OS.SetRect(r, (short) x, (short) y, (short) (x + width),
366: (short) (y + height));
367: OS.RectRgn(rectRgn, r);
368: OS.SectRgn(handle, rectRgn, handle);
369: OS.DisposeRgn(rectRgn);
370: }
371:
372: /**
373: * Intersects all of the polygons which make up the area covered
374: * by the argument to the collection of polygons the receiver
375: * maintains to describe its area.
376: *
377: * @param region the region to intersect
378: *
379: * @exception IllegalArgumentException <ul>
380: * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
381: * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
382: * </ul>
383: * @exception SWTException <ul>
384: * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
385: * </ul>
386: *
387: * @since 3.0
388: */
389: public void intersect(Region region) {
390: if (isDisposed())
391: SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
392: if (region == null)
393: SWT.error(SWT.ERROR_NULL_ARGUMENT);
394: if (region.isDisposed())
395: SWT.error(SWT.ERROR_INVALID_ARGUMENT);
396: OS.SectRgn(handle, region.handle, handle);
397: }
398:
399: /**
400: * Returns <code>true</code> if the rectangle described by the
401: * arguments intersects with any of the polygons the receiver
402: * maintains to describe its area, and <code>false</code> otherwise.
403: *
404: * @param x the x coordinate of the origin of the rectangle
405: * @param y the y coordinate of the origin of the rectangle
406: * @param width the width of the rectangle
407: * @param height the height of the rectangle
408: * @return <code>true</code> if the rectangle intersects with the receiver, and <code>false</code> otherwise
409: *
410: * @exception SWTException <ul>
411: * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
412: * </ul>
413: *
414: * @see Rectangle#intersects(Rectangle)
415: */
416: public boolean intersects(int x, int y, int width, int height) {
417: if (isDisposed())
418: SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
419: Rect rect = new Rect();
420: OS.SetRect(rect, (short) x, (short) y, (short) (x + width),
421: (short) (y + height));
422: return OS.RectInRgn(rect, handle);
423: }
424:
425: /**
426: * Returns <code>true</code> if the given rectangle intersects
427: * with any of the polygons the receiver maintains to describe
428: * its area and <code>false</code> otherwise.
429: *
430: * @param rect the rectangle to test for intersection
431: * @return <code>true</code> if the rectangle intersects with the receiver, and <code>false</code> otherwise
432: *
433: * @exception IllegalArgumentException <ul>
434: * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
435: * </ul>
436: * @exception SWTException <ul>
437: * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
438: * </ul>
439: *
440: * @see Rectangle#intersects(Rectangle)
441: */
442: public boolean intersects(Rectangle rect) {
443: if (rect == null)
444: SWT.error(SWT.ERROR_NULL_ARGUMENT);
445: return intersects(rect.x, rect.y, rect.width, rect.height);
446: }
447:
448: /**
449: * Returns <code>true</code> if the region has been disposed,
450: * and <code>false</code> otherwise.
451: * <p>
452: * This method gets the dispose state for the region.
453: * When a region has been disposed, it is an error to
454: * invoke any other method using the region.
455: *
456: * @return <code>true</code> when the region is disposed, and <code>false</code> otherwise
457: */
458: public boolean isDisposed() {
459: return handle == 0;
460: }
461:
462: /**
463: * Returns <code>true</code> if the receiver does not cover any
464: * area in the (x, y) coordinate plane, and <code>false</code> if
465: * the receiver does cover some area in the plane.
466: *
467: * @return <code>true</code> if the receiver is empty, and <code>false</code> otherwise
468: *
469: * @exception SWTException <ul>
470: * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
471: * </ul>
472: */
473: public boolean isEmpty() {
474: if (isDisposed())
475: SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
476: return OS.EmptyRgn(handle);
477: }
478:
479: /**
480: * Subtracts the given polygon from the collection of polygons
481: * the receiver maintains to describe its area.
482: *
483: * @param pointArray points that describe the polygon to merge with the receiver
484: *
485: * @exception IllegalArgumentException <ul>
486: * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
487: * </ul>
488: * @exception SWTException <ul>
489: * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
490: * </ul>
491: *
492: * @since 3.0
493: */
494: public void subtract(int[] pointArray) {
495: if (isDisposed())
496: SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
497: if (pointArray == null)
498: SWT.error(SWT.ERROR_NULL_ARGUMENT);
499: if (pointArray.length < 2)
500: return;
501: int polyRgn = OS.NewRgn();
502: OS.OpenRgn();
503: OS.MoveTo((short) pointArray[0], (short) pointArray[1]);
504: for (int i = 1; i < pointArray.length / 2; i++) {
505: OS.LineTo((short) pointArray[2 * i],
506: (short) pointArray[2 * i + 1]);
507: }
508: OS.LineTo((short) pointArray[0], (short) pointArray[1]);
509: OS.CloseRgn(polyRgn);
510: OS.DiffRgn(handle, polyRgn, handle);
511: OS.DisposeRgn(polyRgn);
512: }
513:
514: /**
515: * Subtracts the given rectangle from the collection of polygons
516: * the receiver maintains to describe its area.
517: *
518: * @param rect the rectangle to subtract from the receiver
519: *
520: * @exception IllegalArgumentException <ul>
521: * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
522: * <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or height is negative</li>
523: * </ul>
524: * @exception SWTException <ul>
525: * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
526: * </ul>
527: *
528: * @since 3.0
529: */
530: public void subtract(Rectangle rect) {
531: if (isDisposed())
532: SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
533: if (rect == null)
534: SWT.error(SWT.ERROR_NULL_ARGUMENT);
535: subtract(rect.x, rect.y, rect.width, rect.height);
536: }
537:
538: /**
539: * Subtracts the given rectangle from the collection of polygons
540: * the receiver maintains to describe its area.
541: *
542: * @param x the x coordinate of the rectangle
543: * @param y the y coordinate of the rectangle
544: * @param width the width coordinate of the rectangle
545: * @param height the height coordinate of the rectangle
546: *
547: * @exception IllegalArgumentException <ul>
548: * <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or height is negative</li>
549: * </ul>
550: * @exception SWTException <ul>
551: * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
552: * </ul>
553: *
554: * @since 3.1
555: */
556: public void subtract(int x, int y, int width, int height) {
557: if (isDisposed())
558: SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
559: if (width < 0 || height < 0)
560: SWT.error(SWT.ERROR_INVALID_ARGUMENT);
561: int rectRgn = OS.NewRgn();
562: Rect r = new Rect();
563: OS.SetRect(r, (short) x, (short) y, (short) (x + width),
564: (short) (y + height));
565: OS.RectRgn(rectRgn, r);
566: OS.DiffRgn(handle, rectRgn, handle);
567: OS.DisposeRgn(rectRgn);
568: }
569:
570: /**
571: * Subtracts all of the polygons which make up the area covered
572: * by the argument from the collection of polygons the receiver
573: * maintains to describe its area.
574: *
575: * @param region the region to subtract
576: *
577: * @exception IllegalArgumentException <ul>
578: * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
579: * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li>
580: * </ul>
581: * @exception SWTException <ul>
582: * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
583: * </ul>
584: *
585: * @since 3.0
586: */
587: public void subtract(Region region) {
588: if (isDisposed())
589: SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
590: if (region == null)
591: SWT.error(SWT.ERROR_NULL_ARGUMENT);
592: if (region.isDisposed())
593: SWT.error(SWT.ERROR_INVALID_ARGUMENT);
594: OS.DiffRgn(handle, region.handle, handle);
595: }
596:
597: /**
598: * Translate all of the polygons the receiver maintains to describe
599: * its area by the specified point.
600: *
601: * @param x the x coordinate of the point to translate
602: * @param y the y coordinate of the point to translate
603: *
604: * @exception SWTException <ul>
605: * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
606: * </ul>
607: *
608: * @since 3.1
609: */
610: public void translate(int x, int y) {
611: if (isDisposed())
612: SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
613: OS.OffsetRgn(handle, (short) x, (short) y);
614: }
615:
616: /**
617: * Translate all of the polygons the receiver maintains to describe
618: * its area by the specified point.
619: *
620: * @param pt the point to translate
621: *
622: * @exception IllegalArgumentException <ul>
623: * <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
624: * </ul>
625: * @exception SWTException <ul>
626: * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
627: * </ul>
628: *
629: * @since 3.1
630: */
631: public void translate(Point pt) {
632: if (isDisposed())
633: SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
634: if (pt == null)
635: SWT.error(SWT.ERROR_NULL_ARGUMENT);
636: translate(pt.x, pt.y);
637: }
638:
639: /**
640: * Returns a string containing a concise, human-readable
641: * description of the receiver.
642: *
643: * @return a string representation of the receiver
644: */
645: public String toString() {
646: if (isDisposed())
647: return "Region {*DISPOSED*}";
648: return "Region {" + handle + "}";
649: }
650: }
|