Mercurial > projects > dwt-mac
diff dwt/graphics/Region.d @ 45:d8635bb48c7c
Merge with SWT 3.5
author | Jacob Carlborg <doob@me.com> |
---|---|
date | Mon, 01 Dec 2008 17:07:00 +0100 |
parents | 642f460a0908 |
children | cfa563df4fdd |
line wrap: on
line diff
--- a/dwt/graphics/Region.d Tue Oct 21 15:20:04 2008 +0200 +++ b/dwt/graphics/Region.d Mon Dec 01 17:07:00 2008 +0100 @@ -1,5 +1,5 @@ -/******************************************************************************* - * Copyright (c) 2000, 2005 IBM Corporation and others. +/******************************************************************************* + * Copyright (c) 2000, 2008 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 @@ -9,7 +9,7 @@ * IBM Corporation - initial API and implementation * * Port to the D programming language: - * Jacob Carlborg <jacob.carlborg@gmail.com> + * Jacob Carlborg <doob@me.com> *******************************************************************************/ module dwt.graphics.Region; @@ -17,10 +17,13 @@ import dwt.DWT; import dwt.DWTError; import dwt.DWTException; +import dwt.internal.C; import dwt.internal.cocoa.NSAffineTransform; +import dwt.internal.cocoa.NSAutoreleasePool; import dwt.internal.cocoa.NSBezierPath; import dwt.internal.cocoa.NSPoint; import dwt.internal.cocoa.NSRect; +import dwt.internal.cocoa.NSThread; import dwt.internal.cocoa.OS; import tango.text.convert.Format; @@ -43,6 +46,9 @@ * method to release the operating system resources managed by each instance * when those instances are no longer required. * </p> + * + * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Example: GraphicsExample</a> + * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> */ public final class Region : Resource { @@ -92,9 +98,15 @@ */ public this(Device device) { super(device); - handle = OS.NewRgn(); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); + try { + handle = OS.NewRgn(); if (handle is null) DWT.error(DWT.ERROR_NO_HANDLES); init_(); + } finally { + if (pool !is null) pool.release(); + } } this(Device device, QuickdrawTypes.RgnHandle handle) { @@ -102,6 +114,78 @@ this.handle = handle; } +public static Region cocoa_new(Device device, int handle) { + return new Region(device, handle); +} + +static int /*long*/ polyToRgn(int[] poly, int length) { + short[] r = new short[4]; + int /*long*/ polyRgn = OS.NewRgn(), rectRgn = OS.NewRgn(); + int minY = poly[1], maxY = poly[1]; + for (int y = 3; y < length; y += 2) { + if (poly[y] < minY) minY = poly[y]; + if (poly[y] > maxY) maxY = poly[y]; + } + int[] inter = new int[length + 1]; + for (int y = minY; y <= maxY; y++) { + int count = 0; + int x1 = poly[0], y1 = poly[1]; + for (int p = 2; p < length; p += 2) { + int x2 = poly[p], y2 = poly[p + 1]; + if (y1 !is y2 && ((y1 <= y && y < y2) || (y2 <= y && y < y1))) { + inter[count++] = (int)((((y - y1) / (float)(y2 - y1)) * (x2 - x1)) + x1 + 0.5f); + } + x1 = x2; + y1 = y2; + } + int x2 = poly[0], y2 = poly[1]; + if (y1 !is y2 && ((y1 <= y && y < y2) || (y2 <= y && y < y1))) { + inter[count++] = (int)((((y - y1) / (float)(y2 - y1)) * (x2 - x1)) + x1 + 0.5f); + } + for (int gap=count/2; gap>0; gap/=2) { + for (int i=gap; i<count; i++) { + for (int j=i-gap; j>=0; j-=gap) { + if ((inter[j] - inter[j + gap]) <= 0) + break; + int temp = inter[j]; + inter[j] = inter[j + gap]; + inter[j + gap] = temp; + } + } + } + for (int i = 0; i < count; i += 2) { + OS.SetRect(r, (short)inter[i], (short)y, (short)(inter[i + 1]),(short)(y + 1)); + OS.RectRgn(rectRgn, r); + OS.UnionRgn(polyRgn, rectRgn, polyRgn); + } + } + OS.DisposeRgn(rectRgn); + return polyRgn; +} + +static int /*long*/ polyRgn(int[] pointArray, int count) { + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); + try { + int /*long*/ polyRgn; + if (C.PTR_SIZEOF is 4) { + polyRgn = OS.NewRgn(); + OS.OpenRgn(); + OS.MoveTo((short)pointArray[0], (short)pointArray[1]); + for (int i = 1; i < count / 2; i++) { + OS.LineTo((short)pointArray[2 * i], (short)pointArray[2 * i + 1]); + } + OS.LineTo((short)pointArray[0], (short)pointArray[1]); + OS.CloseRgn(polyRgn); + } else { + polyRgn = polyToRgn(pointArray, count); + } + return polyRgn; + } finally { + if (pool !is null) pool.release(); + } +} + /** * Adds the given polygon to the collection of polygons * the receiver maintains to describe its area. @@ -121,21 +205,26 @@ public void add (int[] pointArray) { if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); if (pointArray is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); - add(pointArray, pointArray.length); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); + try { + add(pointArray, pointArray.length); + } finally { + if (pool !is null) pool.release(); + } } void add(int[] pointArray, int count) { if (count <= 2) return; - QuickdrawTypes.RgnHandle polyRgn = OS.NewRgn(); - OS.OpenRgn(); - OS.MoveTo(cast(short)pointArray[0], cast(short)pointArray[1]); - for (int i = 1; i < count / 2; i++) { - OS.LineTo(cast(short)pointArray[2 * i], cast(short)pointArray[2 * i + 1]); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init(); + try { + int /*long*/ polyRgn = polyRgn(pointArray, count); + OS.UnionRgn(handle, polyRgn, handle); + OS.DisposeRgn(polyRgn); + } finally { + if (pool !is null) pool.release(); } - OS.LineTo(cast(short)pointArray[0], cast(short)pointArray[1]); - OS.CloseRgn(polyRgn); - OS.UnionRgn(handle, polyRgn, handle); - OS.DisposeRgn(polyRgn); } /** @@ -156,7 +245,13 @@ if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); if (rect is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); if (rect.width < 0 || rect.height < 0) DWT.error(DWT.ERROR_INVALID_ARGUMENT); - add (rect.x, rect.y, rect.width, rect.height); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); + try { + add (rect.x, rect.y, rect.width, rect.height); + } finally { + if (pool !is null) pool.release(); + } } /** @@ -180,12 +275,18 @@ 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); - QuickdrawTypes.RgnHandle rectRgn = OS.NewRgn(); - Rect r; - OS.SetRect(&r, cast(short)x, cast(short)y, cast(short)(x + width),cast(short)(y + height)); - OS.RectRgn(rectRgn, &r); - OS.UnionRgn(handle, rectRgn, handle); - OS.DisposeRgn(rectRgn); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init(); + try { + QuickdrawTypes.RgnHandle rectRgn = OS.NewRgn(); + Rect r; + OS.SetRect(&r, cast(short)x, cast(short)y, cast(short)(x + width),cast(short)(y + height)); + OS.RectRgn(rectRgn, &r); + OS.UnionRgn(handle, rectRgn, handle); + OS.DisposeRgn(rectRgn); + } finally { + if (pool !is null) pool.release(); + } } /** @@ -207,7 +308,13 @@ 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.UnionRgn(handle, region.handle, handle); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); + try { + OS.UnionRgn(handle, region.handle, handle); + } finally { + if (pool !is null) pool.release(); + } } /** @@ -225,8 +332,14 @@ */ public bool contains(int x, int y) { if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - QuickdrawTypes.Point point = {cast(short)x, cast(short)y}; - return OS.PtInRgn(point, handle); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init(); + try { + QuickdrawTypes.Point point = {cast(short)x, cast(short)y}; + return OS.PtInRgn(point, handle); + } finally { + if (pool !is null) pool.release(); + } } /** @@ -264,29 +377,30 @@ if (message is OS.kQDRegionToRectsMsgParse) { Rect rect; OS.memmove(&rect, r, rect.sizeof); - NSPoint point = NSPoint(); - QuickdrawTypes.RgnHandle polyRgn = OS.NewRgn(); - OS.OpenRgn(); + int i = 0; + NSPoint point = NSPoint(); + int[] points = new int[10]; point.x = rect.left; point.y = rect.top; point = transform.transformPoint(point); short startX, startY; - OS.MoveTo(startX = cast(short)point.x, startY = cast(short)point.y); - point.x = rect.right; + points[i++] = startX = (short)point.x; + points[i++] = startY = (short)point.y; point.y = rect.top; point = transform.transformPoint(point); - OS.LineTo(cast(short)Math.round(point.x), cast(short)point.y); - point.x = rect.right; + points[i++] = (short)Math.round(point.x); + points[i++] = (short)point.y; point.y = rect.bottom; point = transform.transformPoint(point); - OS.LineTo(cast(short)Math.round(point.x), cast(short)Math.round(point.y)); - point.x = rect.left; + points[i++] = (short)Math.round(point.x); + points[i++] = (short)Math.round(point.y); point.y = rect.bottom; point = transform.transformPoint(point); - OS.LineTo(cast(short)point.x, cast(short)Math.round(point.y)); - OS.LineTo(startX, startY); - OS.CloseRgn(polyRgn); - OS.UnionRgn(cast(QuickdrawTypes.RgnHandle) newRgn, polyRgn, cast(QuickdrawTypes.RgnHandle) newRgn); + points[i++] = (short)point.x; + points[i++] = (short)Math.round(point.y); + points[i++] = startX; + points[i++] = startY; + int /*long*/ polyRgn = polyRgn(points, points.length); OS.DisposeRgn(polyRgn); } return null; @@ -331,11 +445,18 @@ */ public Rectangle getBounds() { if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); + NSAutoreleasePool pool = null; Rect bounds; + + if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init(); + try { OS.GetRegionBounds(handle, &bounds); int width = bounds.right - bounds.left; int height = bounds.bottom - bounds.left; return new Rectangle(bounds.left, bounds.top, width, height); + } finally { + if (pool !is null) pool.release(); + } } NSBezierPath getPath() { @@ -348,28 +469,24 @@ static NSPoint pt = NSPoint(); static Rect rect; -extern(C) private static OSStatus* regionToRects(ushort message, QuickdrawTypes.RgnHandle rgn, Rect* r, void* path) { +extern(C) private static OSStatus* regionToRects(ushort message, QuickdrawTypes.RgnHandle rgn, Rect* r, objc.id path) { if (message is OS.kQDRegionToRectsMsgParse) { OS.memmove(&rect, r, rect.sizeof); pt.x = rect.left; pt.y = rect.top; - OS.objc_msgSend(cast(objc.id) path, OS.sel_moveToPoint_1, pt); + OS.objc_msgSend(path, OS.sel_moveToPoint_, pt); pt.x = rect.right; - OS.objc_msgSend(cast(objc.id) path, OS.sel_lineToPoint_1, pt); + OS.objc_msgSend(path, OS.sel_lineToPoint_, pt); pt.x = rect.right; pt.y = rect.bottom; - OS.objc_msgSend(cast(objc.id) path, OS.sel_lineToPoint_1, pt); + OS.objc_msgSend(path, OS.sel_lineToPoint_, pt); pt.x = rect.left; - OS.objc_msgSend(cast(objc.id) path, OS.sel_lineToPoint_1, pt); - OS.objc_msgSend(cast(objc.id) path, OS.sel_closePath); + OS.objc_msgSend(path, OS.sel_lineToPoint_, pt); + OS.objc_msgSend(path, OS.sel_closePath); } return null; } -public static Region carbon_new(Device device, QuickdrawTypes.RgnHandle handle) { - return new Region(device, handle); -} - /** * Returns an integer hash code for the receiver. Any two * objects that return <code>true</code> when passed to @@ -429,12 +546,18 @@ 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); - QuickdrawTypes.RgnHandle rectRgn = OS.NewRgn(); - Rect r; - OS.SetRect(&r, cast(short)x, cast(short)y, cast(short)(x + width),cast(short)(y + height)); - OS.RectRgn(rectRgn, &r); - OS.SectRgn(handle, rectRgn, handle); - OS.DisposeRgn(rectRgn); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); + try { + QuickdrawTypes.RgnHandle rectRgn = OS.NewRgn(); + Rect r; + OS.SetRect(&r, cast(short)x, cast(short)y, cast(short)(x + width),cast(short)(y + height)); + OS.RectRgn(rectRgn, &r); + OS.SectRgn(handle, rectRgn, handle); + OS.DisposeRgn(rectRgn); + } finally { + if (pool !is null) pool.release(); + } } /** @@ -458,7 +581,13 @@ 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.SectRgn(handle, region.handle, handle); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); + try { + OS.SectRgn(handle, region.handle, handle); + } finally { + if (pool !is null) pool.release(); + } } /** @@ -480,9 +609,15 @@ */ public bool intersects (int x, int y, int width, int height) { if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - Rect r; - OS.SetRect(&r, cast(short)x, cast(short)y, cast(short)(x + width),cast(short)(y + height)); - return OS.RectInRgn(&rect, handle); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init(); + try { + Rect r; + OS.SetRect(&r, cast(short)x, cast(short)y, cast(short)(x + width),cast(short)(y + height)); + return OS.RectInRgn(&rect, handle); + } finally { + if (pool !is null) pool.release(); + } } /** @@ -534,7 +669,13 @@ */ public bool isEmpty() { if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - return OS.EmptyRgn(handle); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); + try { + return OS.EmptyRgn(handle); + } finally { + if (pool !is null) pool.release(); + } } /** @@ -556,16 +697,15 @@ if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); if (pointArray is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); if (pointArray.length < 2) return; - QuickdrawTypes.RgnHandle polyRgn = OS.NewRgn(); - OS.OpenRgn(); - OS.MoveTo(cast(short)pointArray[0], cast(short)pointArray[1]); - for (int i = 1; i < pointArray.length / 2; i++) { - OS.LineTo(cast(short)pointArray[2 * i], cast(short)pointArray[2 * i + 1]); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init(); + try { + int /*long*/ polyRgn = polyRgn(pointArray, pointArray.length); + OS.DiffRgn(handle, polyRgn, handle); + OS.DisposeRgn(polyRgn); + } finally { + if (pool !is null) pool.release(); } - OS.LineTo(cast(short)pointArray[0], cast(short)pointArray[1]); - OS.CloseRgn(polyRgn); - OS.DiffRgn(handle, polyRgn, handle); - OS.DisposeRgn(polyRgn); } /** @@ -611,12 +751,18 @@ 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); - QuickdrawTypes.RgnHandle rectRgn = OS.NewRgn(); - Rect r; - OS.SetRect(&r, cast(short)x, cast(short)y, cast(short)(x + width),cast(short)(y + height)); - OS.RectRgn(rectRgn, &r); - OS.DiffRgn(handle, rectRgn, handle); - OS.DisposeRgn(rectRgn); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init(); + try { + int /*long*/ rectRgn = OS.NewRgn(); + Rect r; + OS.SetRect(&r, cast(short)x, cast(short)y, cast(short)(x + width),cast(short)(y + height)); + OS.RectRgn(rectRgn, &r); + OS.DiffRgn(handle, rectRgn, handle); + OS.DisposeRgn(rectRgn); + } finally { + if (pool !is null) pool.release(); + } } /** @@ -640,7 +786,13 @@ 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.DiffRgn(handle, region.handle, handle); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init(); + try { + OS.DiffRgn(handle, region.handle, handle); + } finally { + if (pool !is null) pool.release(); + } } /** @@ -658,7 +810,13 @@ */ public void translate (int x, int y) { if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - OS.OffsetRgn (handle, cast(short)x, cast(short)y); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init(); + try { + OS.OffsetRgn (handle, cast(short)x, cast(short)y); + } finally { + if (pool !is null) pool.release(); + } } /** @@ -679,7 +837,13 @@ 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); + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); + try { + translate (pt.x, pt.y); + } finally { + if (pool !is null) pool.release(); + } } /**