# HG changeset patch # User Frank Benoit # Date 1201353567 -3600 # Node ID 456f604d8a07792f7e2c6d93d60966125108004a # Parent ded98545bb1f1bfac9857ef8c2d087cb22af2568 Region diff -r ded98545bb1f -r 456f604d8a07 dwt/graphics/Region.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt/graphics/Region.d Sat Jan 26 14:19:27 2008 +0100 @@ -0,0 +1,614 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +module dwt.graphics.Region; + + +import dwt.DWT; +import dwt.DWTError; +import dwt.DWTException; +import dwt.internal.win32.OS; + +import dwt.graphics.Resource; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.graphics.Device; + +import tango.text.convert.Format; + +/** + * Instances of this class represent areas of an x-y coordinate + * system that are aggregates of the areas covered by a number + * of polygons. + *

+ * Application code must explicitly invoke the Region.dispose() + * method to release the operating system resources managed by each instance + * when those instances are no longer required. + *

+ */ + +public final class Region : Resource { + + /** + * the OS resource for the region + * (Warning: This field is platform dependent) + *

+ * IMPORTANT: This field is not part of the DWT + * public API. It is marked public only so that it can be shared + * within the packages provided by DWT. It is not available on all + * platforms and should never be accessed from application code. + *

+ */ + public HRGN handle; + +/** + * Constructs a new empty region. + * + * @exception DWTError + */ +public this () { + this(null); +} + +/** + * Constructs a new empty region. + *

+ * You must dispose the region when it is no longer required. + *

+ * + * @param device the device on which to allocate the region + * + * @exception IllegalArgumentException + * @exception DWTError + * + * @see #dispose + * + * @since 3.0 + */ +public this (Device device) { + if (device is null) device = Device.getDevice(); + if (device is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); + this.device = device; + handle = OS.CreateRectRgn (0, 0, 0, 0); + if (handle is null) DWT.error(DWT.ERROR_NO_HANDLES); + if (device.tracking) device.new_Object(this); +} + +/** + * Constructs a new region given a handle to the operating + * system resources that it should represent. + * + * @param handle the handle for the result + */ +this(Device device, HRGN handle) { + this.device = device; + this.handle = handle; +} + +/** + * Adds the given polygon to the collection of polygons + * the receiver maintains to describe its area. + * + * @param pointArray points that describe the polygon to merge with the receiver + * + * @exception IllegalArgumentException + * @exception DWTException + * + * @since 3.0 +* + */ +public void add (int[] pointArray) { + if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); + if (pointArray is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); + if (OS.IsWinCE) DWT.error(DWT.ERROR_NOT_IMPLEMENTED); + auto polyRgn = OS.CreatePolygonRgn(cast(POINT*)pointArray.ptr, pointArray.length / 2, OS.ALTERNATE); + OS.CombineRgn (handle, handle, polyRgn, OS.RGN_OR); + OS.DeleteObject (polyRgn); +} + +/** + * Adds the given rectangle to the collection of polygons + * the receiver maintains to describe its area. + * + * @param rect the rectangle to merge with the receiver + * + * @exception IllegalArgumentException + * @exception DWTException + */ +public void add (Rectangle rect) { + if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); + if (rect is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); + add (rect.x, rect.y, rect.width, rect.height); +} + +/** + * Adds the given rectangle to the collection of polygons + * the receiver maintains to describe its area. + * + * @param x the x coordinate of the rectangle + * @param y the y coordinate of the rectangle + * @param width the width coordinate of the rectangle + * @param height the height coordinate of the rectangle + * + * @exception IllegalArgumentException + * @exception DWTException + * + * @since 3.1 + */ +public void add (int x, int y, int width, int height) { + if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); + if (width < 0 || height < 0) DWT.error(DWT.ERROR_INVALID_ARGUMENT); + auto rectRgn = OS.CreateRectRgn (x, y, x + width, y + height); + OS.CombineRgn (handle, handle, rectRgn, OS.RGN_OR); + OS.DeleteObject (rectRgn); +} + +/** + * Adds all of the polygons which make up the area covered + * by the argument to the collection of polygons the receiver + * maintains to describe its area. + * + * @param region the region to merge + * + * @exception IllegalArgumentException + * @exception DWTException + */ +public void add (Region region) { + if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); + if (region is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); + if (region.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); + OS.CombineRgn (handle, handle, region.handle, OS.RGN_OR); +} + +/** + * Returns true if the point specified by the + * arguments is inside the area specified by the receiver, + * and false otherwise. + * + * @param x the x coordinate of the point to test for containment + * @param y the y coordinate of the point to test for containment + * @return true if the region contains the point and false otherwise + * + * @exception DWTException + */ +public bool contains (int x, int y) { + if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); + return cast(bool) OS.PtInRegion (handle, x, y); +} + +/** + * Returns true if the given point is inside the + * area specified by the receiver, and false + * otherwise. + * + * @param pt the point to test for containment + * @return true if the region contains the point and false otherwise + * + * @exception IllegalArgumentException + * @exception DWTException + */ +public bool contains (Point pt) { + if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); + if (pt is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); + return contains(pt.x, pt.y); +} + +/** + * Disposes of the operating system resources associated with + * the region. Applications must dispose of all regions which + * they allocate. + */ +public void dispose () { + if (handle is null) return; + if (device.isDisposed()) return; + OS.DeleteObject(handle); + handle = null; + if (device.tracking) device.dispose_Object(this); + device = null; +} + +/** + * Compares the argument to the receiver, and returns true + * if they represent the same object using a class + * specific comparison. + * + * @param object the object to compare with this object + * @return true if the object is the same as this object and false otherwise + * + * @see #hashCode + */ +public int opEquals (Object object) { + if (this is object) return true; + if (!(cast(Region)object)) return false; + Region rgn = cast(Region)object; + return handle is rgn.handle; +} + +/** + * Returns a rectangle which represents the rectangular + * union of the collection of polygons the receiver + * maintains to describe its area. + * + * @return a bounding rectangle for the region + * + * @exception DWTException + * + * @see Rectangle#union + */ +public Rectangle getBounds() { + if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); + RECT rect; + OS.GetRgnBox(handle, &rect); + return new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); +} + +/** + * Returns an integer hash code for the receiver. Any two + * objects that return true when passed to + * equals must return the same value for this + * method. + * + * @return the receiver's hash + * + * @see #equals + */ +public hash_t toHash () { + return cast(hash_t)handle; +} + +/** + * Intersects the given rectangle to the collection of polygons + * the receiver maintains to describe its area. + * + * @param rect the rectangle to intersect with the receiver + * + * @exception IllegalArgumentException + * @exception DWTException + * + * @since 3.0 + */ +public void intersect (Rectangle rect) { + if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); + if (rect is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); + intersect (rect.x, rect.y, rect.width, rect.height); +} + +/** + * Intersects the given rectangle to the collection of polygons + * the receiver maintains to describe its area. + * + * @param x the x coordinate of the rectangle + * @param y the y coordinate of the rectangle + * @param width the width coordinate of the rectangle + * @param height the height coordinate of the rectangle + * + * @exception IllegalArgumentException + * @exception DWTException + * + * @since 3.1 + */ +public void intersect (int x, int y, int width, int height) { + if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); + if (width < 0 || height < 0) DWT.error(DWT.ERROR_INVALID_ARGUMENT); + auto rectRgn = OS.CreateRectRgn (x, y, x + width, y + height); + OS.CombineRgn (handle, handle, rectRgn, OS.RGN_AND); + OS.DeleteObject (rectRgn); +} + +/** + * Intersects all of the polygons which make up the area covered + * by the argument to the collection of polygons the receiver + * maintains to describe its area. + * + * @param region the region to intersect + * + * @exception IllegalArgumentException + * @exception DWTException + * + * @since 3.0 + */ +public void intersect (Region region) { + if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); + if (region is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); + if (region.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); + OS.CombineRgn (handle, handle, region.handle, OS.RGN_AND); +} + +/** + * Returns true if the rectangle described by the + * arguments intersects with any of the polygons the receiver + * maintains to describe its area, and false otherwise. + * + * @param x the x coordinate of the origin of the rectangle + * @param y the y coordinate of the origin of the rectangle + * @param width the width of the rectangle + * @param height the height of the rectangle + * @return true if the rectangle intersects with the receiver, and false otherwise + * + * @exception DWTException + * + * @see Rectangle#intersects(Rectangle) + */ +public bool intersects (int x, int y, int width, int height) { + if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); + RECT r; + OS.SetRect (&r, x, y, x + width, y + height); + return cast(bool) OS.RectInRegion (handle, &r); +} + +/** + * Returns true if the given rectangle intersects + * with any of the polygons the receiver maintains to describe + * its area and false otherwise. + * + * @param rect the rectangle to test for intersection + * @return true if the rectangle intersects with the receiver, and false otherwise + * + * @exception IllegalArgumentException + * @exception DWTException + * + * @see Rectangle#intersects(Rectangle) + */ +public bool intersects (Rectangle rect) { + if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); + if (rect is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); + return intersects(rect.x, rect.y, rect.width, rect.height); +} + +/** + * Returns true if the region has been disposed, + * and false otherwise. + *

+ * This method gets the dispose state for the region. + * When a region has been disposed, it is an error to + * invoke any other method using the region. + * + * @return true when the region is disposed, and false otherwise + */ +public bool isDisposed() { + return handle is null; +} + +/** + * Returns true if the receiver does not cover any + * area in the (x, y) coordinate plane, and false if + * the receiver does cover some area in the plane. + * + * @return true if the receiver is empty, and false otherwise + * + * @exception DWTException

+ */ +public bool isEmpty () { + if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); + RECT rect; + auto result = OS.GetRgnBox (handle, &rect); + if (result is OS.NULLREGION) return true; + return ((rect.right - rect.left) <= 0) || ((rect.bottom - rect.top) <= 0); +} + +/** + * Subtracts the given polygon from the collection of polygons + * the receiver maintains to describe its area. + * + * @param pointArray points that describe the polygon to merge with the receiver + * + * @exception IllegalArgumentException + * @exception DWTException + * + * @since 3.0 + */ +public void subtract (int[] pointArray) { + if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); + if (pointArray is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); + if (OS.IsWinCE) DWT.error(DWT.ERROR_NOT_IMPLEMENTED); + auto polyRgn = OS.CreatePolygonRgn(cast(POINT*)pointArray.ptr, pointArray.length / 2, OS.ALTERNATE); + OS.CombineRgn (handle, handle, polyRgn, OS.RGN_DIFF); + OS.DeleteObject (polyRgn); +} + +/** + * Subtracts the given rectangle from the collection of polygons + * the receiver maintains to describe its area. + * + * @param rect the rectangle to subtract from the receiver + * + * @exception IllegalArgumentException + * @exception DWTException + * + * @since 3.0 + */ +public void subtract (Rectangle rect) { + if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); + if (rect is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); + subtract (rect.x, rect.y, rect.width, rect.height); +} + +/** + * Subtracts the given rectangle from the collection of polygons + * the receiver maintains to describe its area. + * + * @param x the x coordinate of the rectangle + * @param y the y coordinate of the rectangle + * @param width the width coordinate of the rectangle + * @param height the height coordinate of the rectangle + * + * @exception IllegalArgumentException + * @exception DWTException + * + * @since 3.1 + */ +public void subtract (int x, int y, int width, int height) { + if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); + if (width < 0 || height < 0) DWT.error(DWT.ERROR_INVALID_ARGUMENT); + auto rectRgn = OS.CreateRectRgn (x, y, x + width, y + height); + OS.CombineRgn (handle, handle, rectRgn, OS.RGN_DIFF); + OS.DeleteObject (rectRgn); +} + +/** + * Subtracts all of the polygons which make up the area covered + * by the argument from the collection of polygons the receiver + * maintains to describe its area. + * + * @param region the region to subtract + * + * @exception IllegalArgumentException + * @exception DWTException + * + * @since 3.0 + */ +public void subtract (Region region) { + if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); + if (region is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); + if (region.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); + OS.CombineRgn (handle, handle, region.handle, OS.RGN_DIFF); +} + +/** + * Translate all of the polygons the receiver maintains to describe + * its area by the specified point. + * + * @param x the x coordinate of the point to translate + * @param y the y coordinate of the point to translate + * + * @exception DWTException + * + * @since 3.1 + */ +public void translate (int x, int y) { + if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); + OS.OffsetRgn (handle, x, y); +} + +/** + * Translate all of the polygons the receiver maintains to describe + * its area by the specified point. + * + * @param pt the point to translate + * + * @exception IllegalArgumentException + * @exception DWTException + * + * @since 3.1 + */ +public void translate (Point pt) { + if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); + if (pt is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); + translate (pt.x, pt.y); +} + +/** + * Returns a string containing a concise, human-readable + * description of the receiver. + * + * @return a string representation of the receiver + */ +public char[] toString () { + if (isDisposed()) return "Region {*DISPOSED*}"; + return Format( "Region {{{}}", handle ); +} + +/** + * Invokes platform specific functionality to allocate a new region. + *

+ * IMPORTANT: This method is not part of the public + * API for Region. It is marked public only so that it + * can be shared within the packages provided by DWT. It is not + * available on all platforms, and should never be called from + * application code. + *

+ * + * @param device the device on which to allocate the region + * @param handle the handle for the region + * @return a new region object containing the specified device and handle + */ +public static Region win32_new(Device device, HRGN handle) { + return new Region(device, handle); +} + +}