diff dwt/graphics/Path.d @ 45:d8635bb48c7c

Merge with SWT 3.5
author Jacob Carlborg <doob@me.com>
date Mon, 01 Dec 2008 17:07:00 +0100
parents db5a898b2119
children cfa563df4fdd
line wrap: on
line diff
--- a/dwt/graphics/Path.d	Tue Oct 21 15:20:04 2008 +0200
+++ b/dwt/graphics/Path.d	Mon Dec 01 17:07:00 2008 +0100
@@ -1,5 +1,5 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2007 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.Path;
 
@@ -18,6 +18,7 @@
 import dwt.DWTError;
 import dwt.DWTException;
 import dwt.internal.cocoa.NSAffineTransform;
+import dwt.internal.cocoa.NSAutoreleasePool;
 import dwt.internal.cocoa.NSBezierPath;
 import dwt.internal.cocoa.NSLayoutManager;
 import dwt.internal.cocoa.NSPoint;
@@ -27,6 +28,7 @@
 import dwt.internal.cocoa.NSString;
 import dwt.internal.cocoa.NSTextContainer;
 import dwt.internal.cocoa.NSTextStorage;
+import dwt.internal.cocoa.NSThread;
 import dwt.internal.cocoa.OS;
 
 import tango.text.convert.Format;
@@ -56,6 +58,10 @@
  * This class requires the operating system's advanced graphics subsystem
  * which may not be available on some platforms.
  * </p>
+ *
+ * @see <a href="http://www.eclipse.org/swt/snippets/#path">Path, Pattern snippets</a>
+ * @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>
  * 
  * @since 3.1
  */
@@ -99,34 +105,106 @@
  */
 public this (Device device) {
     super(device);
-    handle = NSBezierPath.bezierPath();
-    if (handle is null) DWT.error(DWT.ERROR_NO_HANDLES);
-    handle.retain();
+    NSAutoreleasePool pool = null;
+    if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
+    try {
+        handle = NSBezierPath.bezierPath();
+        if (handle is null) DWT.error(DWT.ERROR_NO_HANDLES);
+        handle.retain();
     handle.moveToPoint(NSPoint());
     init_();
+    } finally {
+        if (pool !is null) pool.release();
+    }
 }
 
-public this (Device device, Path path, float flatness) {
+/**
+ * Constructs a new Path that is a copy of <code>path</code>. If
+ * <code>flatness</code> is less than or equal to zero, an unflatten
+ * copy of the path is created. Otherwise, it specifies the maximum
+ * error between the path and its flatten copy. Smaller numbers give
+ * better approximation.
+ * <p>
+ * This operation requires the operating system's advanced
+ * graphics subsystem which may not be available on some
+ * platforms.
+ * </p>
+ * 
+ * @param device the device on which to allocate the path
+ * @param path the path to make a copy
+ * @param flatness the flatness value
+ * 
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the device is null and there is no current device</li>
+ *    <li>ERROR_NULL_ARGUMENT - if the path is null</li>
+ *    <li>ERROR_INVALID_ARGUMENT - if the path has been disposed</li>
+ * </ul>
+ * @exception DWTException <ul>
+ *    <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li>
+ * </ul>
+ * @exception DWTError <ul>
+ *    <li>ERROR_NO_HANDLES if a handle for the path could not be obtained</li>
+ * </ul>
+ * 
+ * @see #dispose()
+ * @since 3.4
+ */
     super(device);
-    if (path is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
-    if (path.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
-    flatness = Math.max(0, flatness);
-    if (flatness is 0) {
+    NSAutoreleasePool pool = null;
+    if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
+    try {
+        if (path is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
+        if (path.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
+        flatness = Math.max(0, flatness);
+        if (flatness is 0) {
         handle = new NSBezierPath(path.handle.copy().id_);
-    } else {
+        } else {
         CGFloat defaultFlatness = NSBezierPath.defaultFlatness();
-        NSBezierPath.setDefaultFlatness(flatness);
-        handle = path.handle.bezierPathByFlatteningPath();
-        NSBezierPath.setDefaultFlatness(defaultFlatness);       
+            NSBezierPath.setDefaultFlatness(flatness);
+            handle = path.handle.bezierPathByFlatteningPath();
+            NSBezierPath.setDefaultFlatness(defaultFlatness);       
+        }
+        if (handle is null) DWT.error(DWT.ERROR_NO_HANDLES);
+    init_();
+    } finally {
+        if (pool !is null) pool.release();
     }
-    if (handle is null) DWT.error(DWT.ERROR_NO_HANDLES);
-    init_();
 }
 
-public this (Device device, PathData data) {
+/**
+ * Constructs a new Path with the specifed PathData.
+ * <p>
+ * This operation requires the operating system's advanced
+ * graphics subsystem which may not be available on some
+ * platforms.
+ * </p>
+ * 
+ * @param device the device on which to allocate the path
+ * @param data the data for the path
+ * 
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the device is null and there is no current device</li>
+ *    <li>ERROR_NULL_ARGUMENT - if the data is null</li>
+ * </ul>
+ * @exception DWTException <ul>
+ *    <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li>
+ * </ul>
+ * @exception DWTError <ul>
+ *    <li>ERROR_NO_HANDLES if a handle for the path could not be obtained</li>
+ * </ul>
+ * 
+ * @see #dispose()
+ * @since 3.4
+ */
     this(device);
-    if (data is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
+    NSAutoreleasePool pool = null;
+    if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
+    try {
+        if (data is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
     init_(data);
+    } finally {
+        if (pool !is null) pool.release();
+    }
 }
 
 /**
@@ -160,16 +238,22 @@
  */
 public void addArc(float x, float y, float width, float height, float startAngle, float arcAngle) {
     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
-    NSAffineTransform transform = NSAffineTransform.transform();
-    transform.translateXBy(x + width / 2f, y + height / 2f);
-    transform.scaleXBy(width / 2f, height / 2f);
-    NSBezierPath path = NSBezierPath.bezierPath();
+    NSAutoreleasePool pool = null;
+    if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
+    try {
+        NSAffineTransform transform = NSAffineTransform.transform();
+        transform.translateXBy(x + width / 2f, y + height / 2f);
+        transform.scaleXBy(width / 2f, height / 2f);
+        NSBezierPath path = NSBezierPath.bezierPath();
     NSPoint center = NSPoint();
     CGFloat sAngle = -startAngle;
     CGFloat eAngle = -(startAngle + arcAngle);
-    path.appendBezierPathWithArcWithCenter_radius_startAngle_endAngle_clockwise_(center, 1, sAngle,  eAngle, arcAngle>0);
-    path.transformUsingAffineTransform(transform);
-    handle.appendBezierPath(path);
+        path.appendBezierPathWithArcWithCenter(center, 1, sAngle,  eAngle, arcAngle>0);
+        path.transformUsingAffineTransform(transform);
+        handle.appendBezierPath(path);
+    } finally { 
+        if (pool !is null) pool.release();
+    }
 }
 
 /**
@@ -189,7 +273,13 @@
     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
     if (path is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
     if (path.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
-    handle.appendBezierPath(path.handle);
+    NSAutoreleasePool pool = null;
+    if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
+    try {
+        handle.appendBezierPath(path.handle);
+    } finally {
+        if (pool !is null) pool.release();
+    }
 }
 
 /**
@@ -211,7 +301,13 @@
     rect.y = y;
     rect.width = width;
     rect.height = height;
-    handle.appendBezierPathWithRect(rect);
+    NSAutoreleasePool pool = null;
+    if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
+    try {
+        handle.appendBezierPathWithRect(rect);
+    } finally {
+        if (pool !is null) pool.release();
+    }
 }
 
 /**
@@ -235,42 +331,48 @@
     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
     if (font is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
     if (font.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
-    NSString str = NSString.stringWith(stri);
-    NSTextStorage textStorage = (cast(NSTextStorage)(new NSTextStorage()).alloc());
-    textStorage.initWithString_(str);
+    NSAutoreleasePool pool = null;
+    if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init();
+    try {
+        NSString str = NSString.stringWith(stri);
+        NSTextStorage textStorage = (cast(NSTextStorage)(new NSTextStorage()).alloc());
+        textStorage.initWithString(str);
     NSLayoutManager layoutManager = cast(NSLayoutManager)(new NSLayoutManager()).alloc().init();
     NSTextContainer textContainer = cast(NSTextContainer)(new NSTextContainer()).alloc();
     NSSize size = NSSize();
     size.width = CGFloat.max; //Float.MAX_VALUE;
     size.height = CGFloat.max; //Float.MAX_VALUE;
-    textContainer.initWithContainerSize(size);
-    textStorage.addLayoutManager(layoutManager);
-    layoutManager.addTextContainer(textContainer);
+        textContainer.initWithContainerSize(size);
+        textStorage.addLayoutManager(layoutManager);
+        layoutManager.addTextContainer(textContainer);
     NSRange range = NSRange();
-    range.length = str.length();
-    textStorage.beginEditing();
-    textStorage.addAttribute(OS.NSFontAttributeName(), font.handle, range);
-    textStorage.endEditing();
-    range = layoutManager.glyphRangeForTextContainer(textContainer);
-    if (range.length !is 0) {
+        range.length = str.length();
+        textStorage.beginEditing();
+        textStorage.addAttribute(OS.NSFontAttributeName, font.handle, range);
+        textStorage.endEditing();
+        range = layoutManager.glyphRangeForTextContainer(textContainer);
+        if (range.length !is 0) {
         NSGlyph* glyphs = cast(NSGlyph*) OS.malloc(4 * range.length * 2);
-        layoutManager.getGlyphs(glyphs, range);
-        NSBezierPath path = NSBezierPath.bezierPath();
+            layoutManager.getGlyphs(glyphs, range);
+            NSBezierPath path = NSBezierPath.bezierPath();
         NSPoint point = NSPoint();
-        point.x = x;
-        point.y = y;
-        path.moveToPoint(point);
-        path.appendBezierPathWithGlyphs(glyphs, range.length, font.handle);
-        NSAffineTransform transform = NSAffineTransform.transform();
-        transform.scaleXBy(1, -1);
-        transform.translateXBy(0, -((2*y) + textStorage.size().height));
-        path.transformUsingAffineTransform(transform);
-        OS.free(glyphs);
-        handle.appendBezierPath(path);
+            point.x = x;
+            point.y = y;
+            path.moveToPoint(point);
+            path.appendBezierPathWithGlyphs(glyphs, range.length, font.handle);
+            NSAffineTransform transform = NSAffineTransform.transform();
+            transform.scaleXBy(1, -1);
+            transform.translateXBy(0, -((2*y) + textStorage.size().height));
+            path.transformUsingAffineTransform(transform);
+            OS.free(glyphs);
+            handle.appendBezierPath(path);
+        }
+        textContainer.release();
+        layoutManager.release();
+        textStorage.release();
+    } finally  {
+        if (pool !is null) pool.release();
     }
-    textContainer.release();
-    layoutManager.release();
-    textStorage.release();
 }
 
 /**
@@ -284,7 +386,13 @@
  */
 public void close() {
     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
-    handle.closePath();
+    NSAutoreleasePool pool = null;
+    if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
+    try {
+        handle.closePath();
+    } finally {
+        if (pool !is null) pool.release();
+    }
 }
 
 /**
@@ -314,12 +422,18 @@
     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
     if (gc is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
     if (gc.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
-//  gc.checkGC(GC.LINE_CAP | GC.LINE_JOIN | GC.LINE_STYLE | GC.LINE_WIDTH);
-    //TODO outline
+    NSAutoreleasePool pool = null;
+    if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
+    try {
+        //  gc.checkGC(GC.LINE_CAP | GC.LINE_JOIN | GC.LINE_STYLE | GC.LINE_WIDTH);
+        //TODO outline
     NSPoint point = NSPoint();
-    point.x = x;
-    point.y = y;
-    return handle.containsPoint(point);
+        point.x = x;
+        point.y = y;
+        return handle.containsPoint(point);
+    } finally {
+        if (pool !is null) pool.release();
+    }
 }
 
 /**
@@ -338,16 +452,22 @@
  */
 public void cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y) {
     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
-    NSPoint pt = NSPoint();
-    pt.x = x;
-    pt.y = y;
+    NSAutoreleasePool pool = null;
+    if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
+    try {
+        NSPoint pt = NSPoint();
+        pt.x = x;
+        pt.y = y;
     NSPoint ct1 = NSPoint();
-    ct1.x = cx1;
-    ct1.y = cy1;
+        ct1.x = cx1;
+        ct1.y = cy1;
     NSPoint ct2 = NSPoint();
-    ct2.x = cx2;
-    ct2.y = cy2;
-    handle.curveToPoint(pt, ct1, ct2);
+        ct2.x = cx2;
+        ct2.y = cy2;
+        handle.curveToPoint(pt, ct1, ct2);
+    } finally {
+        if (pool !is null) pool.release();
+    }
 }
 
 void destroy() {
@@ -374,11 +494,17 @@
     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
     if (bounds is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
     if (bounds.length < 4) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
-    NSRect rect = handle.controlPointBounds();
-    bounds[0] = rect.x;
-    bounds[1] = rect.y;
-    bounds[2] = rect.width;
-    bounds[3] = rect.height;
+    NSAutoreleasePool pool = null;
+    if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
+    try {
+        NSRect rect = handle.controlPointBounds();
+        bounds[0] = (float)/*64*/rect.x;
+        bounds[1] = (float)/*64*/rect.y;
+        bounds[2] = (float)/*64*/rect.width;
+        bounds[3] = (float)/*64*/rect.height;
+    } finally {
+        if (pool !is null) pool.release();
+    }
 }
 
 /**
@@ -399,9 +525,15 @@
     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
     if (point is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
     if (point.length < 2) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
-    NSPoint pt = handle.currentPoint();
-    point[0] = pt.x;
-    point[1] = pt.y;
+    NSAutoreleasePool pool = null;
+    if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
+    try {
+        NSPoint pt = handle.currentPoint();
+        point[0] = (float)/*64*/pt.x;
+        point[1] = (float)/*64*/pt.y;
+    } finally {
+        if (pool !is null) pool.release();
+    }
 }
 
 /**
@@ -417,30 +549,33 @@
  */
 public PathData getPathData() {
     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
-    int count = handle.elementCount();
-    int pointCount = 0, typeCount = 0;
-    byte[] types = new byte[count];
-    float[] pointArray = new float[count * 6];
+    NSAutoreleasePool pool = null;
+    if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
+    try {
+        int count = (int)/*64*/handle.elementCount();
+        int pointCount = 0, typeCount = 0;
+        byte[] types = new byte[count];
+        float[] pointArray = new float[count * 6];
     NSPointArray points = cast(NSPointArray) OS.malloc(3 * NSPoint.sizeof);
     if (points is null) DWT.error(DWT.ERROR_NO_HANDLES);
     NSPoint pt = NSPoint();
     for (NSInteger i = 0; i < count; i++) {
-        NSBezierPathElement  element = handle.elementAtIndex_associatedPoints_(i, points);
-        switch (element) {
+        NSBezierPathElement element = handle.elementAtIndex(i, points);
+            switch (element) {
             case NSMoveToBezierPathElement:
-                types[typeCount++] = DWT.PATH_MOVE_TO;
+                    types[typeCount++] = DWT.PATH_MOVE_TO;
                 OS.memmove(&pt, points, NSPoint.sizeof);
                 pointArray[pointCount++] = cast(int)pt.x;
                 pointArray[pointCount++] = cast(int)pt.y;
-                break;
+                    break;
             case NSLineToBezierPathElement:
-                types[typeCount++] = DWT.PATH_LINE_TO;
+                    types[typeCount++] = DWT.PATH_LINE_TO;
                 OS.memmove(&pt, points, NSPoint.sizeof);
                 pointArray[pointCount++] = cast(int)pt.x;
                 pointArray[pointCount++] = cast(int)pt.y;
-                break;
+                    break;
             case NSCurveToBezierPathElement:
-                types[typeCount++] = DWT.PATH_CUBIC_TO;
+                    types[typeCount++] = DWT.PATH_CUBIC_TO;
                 OS.memmove(&pt, points, NSPoint.sizeof);
                 pointArray[pointCount++] = cast(int)pt.x;
                 pointArray[pointCount++] = cast(int)pt.y;
@@ -450,22 +585,25 @@
                 OS.memmove(&pt, points + NSPoint.sizeof + NSPoint.sizeof, NSPoint.sizeof);
                 pointArray[pointCount++] = cast(int)pt.x;
                 pointArray[pointCount++] = cast(int)pt.y;
-                break;
+                    break;
             case NSClosePathBezierPathElement:
-                types[typeCount++] = DWT.PATH_CLOSE;
-                break;
+                    types[typeCount++] = DWT.PATH_CLOSE;
+                    break;
+            }
         }
+        OS.free(points);
+        if (pointCount !is pointArray.length) {
+            float[] temp = new float[pointCount];
+            System.arraycopy(pointArray, 0, temp, 0, pointCount);
+            pointArray = temp;
+        }
+        PathData data = new PathData();
+        data.types = types;
+        data.points = pointArray;
+        return data;
+    } finally {
+        if (pool !is null)  pool.release();
     }
-    OS.free(points);
-    if (pointCount !is pointArray.length) {
-        float[] temp = new float[pointCount];
-        System.arraycopy(pointArray, 0, temp, 0, pointCount);
-        pointArray = temp;
-    }
-    PathData data = new PathData();
-    data.types = types;
-    data.points = pointArray;
-    return data;
 }
 
 void init_(PathData data) {
@@ -522,10 +660,16 @@
  */
 public void lineTo(float x, float y) {
     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
-    NSPoint pt = NSPoint();
-    pt.x = x;
-    pt.y = y;
-    handle.lineToPoint(pt);
+    NSAutoreleasePool pool = null;
+    if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
+    try {
+        NSPoint pt = NSPoint();
+        pt.x = x;
+        pt.y = y;
+        handle.lineToPoint(pt);
+    } finally {
+        if (pool !is null) pool.release();
+    }
 }
 
 /**
@@ -542,11 +686,16 @@
  */
 public void moveTo(float x, float y) {
     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
-    NSPoint pt = NSPoint();
-    pt.x = x;
-    pt.y = y;
-    handle.moveToPoint(pt);
-
+    NSAutoreleasePool pool = null;
+    if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init();
+    try {
+        NSPoint pt = NSPoint();
+        pt.x = x;
+        pt.y = y;
+        handle.moveToPoint(pt);
+    } finally {
+        if (pool !is null) pool.release();
+    }
 }
 
 /**
@@ -563,13 +712,19 @@
  */
 public void quadTo(float cx, float cy, float x, float y) {
     if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
-    NSPoint pt = NSPoint();
-    pt.x = x;
-    pt.y = y;
+    NSAutoreleasePool pool = null;
+    if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init();
+    try {
+        NSPoint pt = NSPoint();
+        pt.x = x;
+        pt.y = y;
     NSPoint ct = NSPoint();
-    ct.x = cx;
-    ct.y = cy;
-    handle.curveToPoint(pt, ct, ct);
+        ct.x = cx;
+        ct.y = cy;
+        handle.curveToPoint(pt, ct, ct);
+    } finally {
+        if (pool !is null) pool.release();
+    }
 }
 
 /**