comparison 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
comparison
equal deleted inserted replaced
44:ca5e494f2bbf 45:d8635bb48c7c
1 /******************************************************************************* 1 /*******************************************************************************
2 * Copyright (c) 2000, 2007 IBM Corporation and others. 2 * Copyright (c) 2000, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials 3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0 4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at 5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html 6 * http://www.eclipse.org/legal/epl-v10.html
7 * 7 *
8 * Contributors: 8 * Contributors:
9 * IBM Corporation - initial API and implementation 9 * IBM Corporation - initial API and implementation
10 * 10 *
11 * Port to the D programming language: 11 * Port to the D programming language:
12 * Jacob Carlborg <jacob.carlborg@gmail.com> 12 * Jacob Carlborg <doob@me.com>
13 *******************************************************************************/ 13 *******************************************************************************/
14 module dwt.graphics.Path; 14 module dwt.graphics.Path;
15 15
16 16
17 import dwt.DWT; 17 import dwt.DWT;
18 import dwt.DWTError; 18 import dwt.DWTError;
19 import dwt.DWTException; 19 import dwt.DWTException;
20 import dwt.internal.cocoa.NSAffineTransform; 20 import dwt.internal.cocoa.NSAffineTransform;
21 import dwt.internal.cocoa.NSAutoreleasePool;
21 import dwt.internal.cocoa.NSBezierPath; 22 import dwt.internal.cocoa.NSBezierPath;
22 import dwt.internal.cocoa.NSLayoutManager; 23 import dwt.internal.cocoa.NSLayoutManager;
23 import dwt.internal.cocoa.NSPoint; 24 import dwt.internal.cocoa.NSPoint;
24 import dwt.internal.cocoa.NSRange; 25 import dwt.internal.cocoa.NSRange;
25 import dwt.internal.cocoa.NSRect; 26 import dwt.internal.cocoa.NSRect;
26 import dwt.internal.cocoa.NSSize; 27 import dwt.internal.cocoa.NSSize;
27 import dwt.internal.cocoa.NSString; 28 import dwt.internal.cocoa.NSString;
28 import dwt.internal.cocoa.NSTextContainer; 29 import dwt.internal.cocoa.NSTextContainer;
29 import dwt.internal.cocoa.NSTextStorage; 30 import dwt.internal.cocoa.NSTextStorage;
31 import dwt.internal.cocoa.NSThread;
30 import dwt.internal.cocoa.OS; 32 import dwt.internal.cocoa.OS;
31 33
32 import tango.text.convert.Format; 34 import tango.text.convert.Format;
33 35
34 import dwt.dwthelper.utils; 36 import dwt.dwthelper.utils;
54 * </p> 56 * </p>
55 * <p> 57 * <p>
56 * This class requires the operating system's advanced graphics subsystem 58 * This class requires the operating system's advanced graphics subsystem
57 * which may not be available on some platforms. 59 * which may not be available on some platforms.
58 * </p> 60 * </p>
61 *
62 * @see <a href="http://www.eclipse.org/swt/snippets/#path">Path, Pattern snippets</a>
63 * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Example: GraphicsExample</a>
64 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
59 * 65 *
60 * @since 3.1 66 * @since 3.1
61 */ 67 */
62 public class Path : Resource { 68 public class Path : Resource {
63 69
97 * 103 *
98 * @see #dispose() 104 * @see #dispose()
99 */ 105 */
100 public this (Device device) { 106 public this (Device device) {
101 super(device); 107 super(device);
102 handle = NSBezierPath.bezierPath(); 108 NSAutoreleasePool pool = null;
103 if (handle is null) DWT.error(DWT.ERROR_NO_HANDLES); 109 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
104 handle.retain(); 110 try {
111 handle = NSBezierPath.bezierPath();
112 if (handle is null) DWT.error(DWT.ERROR_NO_HANDLES);
113 handle.retain();
105 handle.moveToPoint(NSPoint()); 114 handle.moveToPoint(NSPoint());
106 init_(); 115 init_();
107 } 116 } finally {
108 117 if (pool !is null) pool.release();
109 public this (Device device, Path path, float flatness) { 118 }
119 }
120
121 /**
122 * Constructs a new Path that is a copy of <code>path</code>. If
123 * <code>flatness</code> is less than or equal to zero, an unflatten
124 * copy of the path is created. Otherwise, it specifies the maximum
125 * error between the path and its flatten copy. Smaller numbers give
126 * better approximation.
127 * <p>
128 * This operation requires the operating system's advanced
129 * graphics subsystem which may not be available on some
130 * platforms.
131 * </p>
132 *
133 * @param device the device on which to allocate the path
134 * @param path the path to make a copy
135 * @param flatness the flatness value
136 *
137 * @exception IllegalArgumentException <ul>
138 * <li>ERROR_NULL_ARGUMENT - if the device is null and there is no current device</li>
139 * <li>ERROR_NULL_ARGUMENT - if the path is null</li>
140 * <li>ERROR_INVALID_ARGUMENT - if the path has been disposed</li>
141 * </ul>
142 * @exception DWTException <ul>
143 * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li>
144 * </ul>
145 * @exception DWTError <ul>
146 * <li>ERROR_NO_HANDLES if a handle for the path could not be obtained</li>
147 * </ul>
148 *
149 * @see #dispose()
150 * @since 3.4
151 */
110 super(device); 152 super(device);
111 if (path is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); 153 NSAutoreleasePool pool = null;
112 if (path.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); 154 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
113 flatness = Math.max(0, flatness); 155 try {
114 if (flatness is 0) { 156 if (path is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
157 if (path.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
158 flatness = Math.max(0, flatness);
159 if (flatness is 0) {
115 handle = new NSBezierPath(path.handle.copy().id_); 160 handle = new NSBezierPath(path.handle.copy().id_);
116 } else { 161 } else {
117 CGFloat defaultFlatness = NSBezierPath.defaultFlatness(); 162 CGFloat defaultFlatness = NSBezierPath.defaultFlatness();
118 NSBezierPath.setDefaultFlatness(flatness); 163 NSBezierPath.setDefaultFlatness(flatness);
119 handle = path.handle.bezierPathByFlatteningPath(); 164 handle = path.handle.bezierPathByFlatteningPath();
120 NSBezierPath.setDefaultFlatness(defaultFlatness); 165 NSBezierPath.setDefaultFlatness(defaultFlatness);
121 } 166 }
122 if (handle is null) DWT.error(DWT.ERROR_NO_HANDLES); 167 if (handle is null) DWT.error(DWT.ERROR_NO_HANDLES);
123 init_(); 168 init_();
124 } 169 } finally {
125 170 if (pool !is null) pool.release();
126 public this (Device device, PathData data) { 171 }
172 }
173
174 /**
175 * Constructs a new Path with the specifed PathData.
176 * <p>
177 * This operation requires the operating system's advanced
178 * graphics subsystem which may not be available on some
179 * platforms.
180 * </p>
181 *
182 * @param device the device on which to allocate the path
183 * @param data the data for the path
184 *
185 * @exception IllegalArgumentException <ul>
186 * <li>ERROR_NULL_ARGUMENT - if the device is null and there is no current device</li>
187 * <li>ERROR_NULL_ARGUMENT - if the data is null</li>
188 * </ul>
189 * @exception DWTException <ul>
190 * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li>
191 * </ul>
192 * @exception DWTError <ul>
193 * <li>ERROR_NO_HANDLES if a handle for the path could not be obtained</li>
194 * </ul>
195 *
196 * @see #dispose()
197 * @since 3.4
198 */
127 this(device); 199 this(device);
128 if (data is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); 200 NSAutoreleasePool pool = null;
201 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
202 try {
203 if (data is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
129 init_(data); 204 init_(data);
205 } finally {
206 if (pool !is null) pool.release();
207 }
130 } 208 }
131 209
132 /** 210 /**
133 * Adds to the receiver a circular or elliptical arc that lies within 211 * Adds to the receiver a circular or elliptical arc that lies within
134 * the specified rectangular area. 212 * the specified rectangular area.
158 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 236 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
159 * </ul> 237 * </ul>
160 */ 238 */
161 public void addArc(float x, float y, float width, float height, float startAngle, float arcAngle) { 239 public void addArc(float x, float y, float width, float height, float startAngle, float arcAngle) {
162 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 240 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
163 NSAffineTransform transform = NSAffineTransform.transform(); 241 NSAutoreleasePool pool = null;
164 transform.translateXBy(x + width / 2f, y + height / 2f); 242 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
165 transform.scaleXBy(width / 2f, height / 2f); 243 try {
166 NSBezierPath path = NSBezierPath.bezierPath(); 244 NSAffineTransform transform = NSAffineTransform.transform();
245 transform.translateXBy(x + width / 2f, y + height / 2f);
246 transform.scaleXBy(width / 2f, height / 2f);
247 NSBezierPath path = NSBezierPath.bezierPath();
167 NSPoint center = NSPoint(); 248 NSPoint center = NSPoint();
168 CGFloat sAngle = -startAngle; 249 CGFloat sAngle = -startAngle;
169 CGFloat eAngle = -(startAngle + arcAngle); 250 CGFloat eAngle = -(startAngle + arcAngle);
170 path.appendBezierPathWithArcWithCenter_radius_startAngle_endAngle_clockwise_(center, 1, sAngle, eAngle, arcAngle>0); 251 path.appendBezierPathWithArcWithCenter(center, 1, sAngle, eAngle, arcAngle>0);
171 path.transformUsingAffineTransform(transform); 252 path.transformUsingAffineTransform(transform);
172 handle.appendBezierPath(path); 253 handle.appendBezierPath(path);
254 } finally {
255 if (pool !is null) pool.release();
256 }
173 } 257 }
174 258
175 /** 259 /**
176 * Adds to the receiver the path described by the parameter. 260 * Adds to the receiver the path described by the parameter.
177 * 261 *
187 */ 271 */
188 public void addPath(Path path) { 272 public void addPath(Path path) {
189 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 273 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
190 if (path is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); 274 if (path is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
191 if (path.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); 275 if (path.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
192 handle.appendBezierPath(path.handle); 276 NSAutoreleasePool pool = null;
277 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
278 try {
279 handle.appendBezierPath(path.handle);
280 } finally {
281 if (pool !is null) pool.release();
282 }
193 } 283 }
194 284
195 /** 285 /**
196 * Adds to the receiver the rectangle specified by x, y, width and height. 286 * Adds to the receiver the rectangle specified by x, y, width and height.
197 * 287 *
209 NSRect rect = NSRect(); 299 NSRect rect = NSRect();
210 rect.x = x; 300 rect.x = x;
211 rect.y = y; 301 rect.y = y;
212 rect.width = width; 302 rect.width = width;
213 rect.height = height; 303 rect.height = height;
214 handle.appendBezierPathWithRect(rect); 304 NSAutoreleasePool pool = null;
305 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
306 try {
307 handle.appendBezierPathWithRect(rect);
308 } finally {
309 if (pool !is null) pool.release();
310 }
215 } 311 }
216 312
217 /** 313 /**
218 * Adds to the receiver the pattern of glyphs generated by drawing 314 * Adds to the receiver the pattern of glyphs generated by drawing
219 * the given string using the given font starting at the point (x, y). 315 * the given string using the given font starting at the point (x, y).
233 */ 329 */
234 public void addString(String stri, float x, float y, Font font) { 330 public void addString(String stri, float x, float y, Font font) {
235 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 331 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
236 if (font is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); 332 if (font is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
237 if (font.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); 333 if (font.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
238 NSString str = NSString.stringWith(stri); 334 NSAutoreleasePool pool = null;
239 NSTextStorage textStorage = (cast(NSTextStorage)(new NSTextStorage()).alloc()); 335 if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init();
240 textStorage.initWithString_(str); 336 try {
337 NSString str = NSString.stringWith(stri);
338 NSTextStorage textStorage = (cast(NSTextStorage)(new NSTextStorage()).alloc());
339 textStorage.initWithString(str);
241 NSLayoutManager layoutManager = cast(NSLayoutManager)(new NSLayoutManager()).alloc().init(); 340 NSLayoutManager layoutManager = cast(NSLayoutManager)(new NSLayoutManager()).alloc().init();
242 NSTextContainer textContainer = cast(NSTextContainer)(new NSTextContainer()).alloc(); 341 NSTextContainer textContainer = cast(NSTextContainer)(new NSTextContainer()).alloc();
243 NSSize size = NSSize(); 342 NSSize size = NSSize();
244 size.width = CGFloat.max; //Float.MAX_VALUE; 343 size.width = CGFloat.max; //Float.MAX_VALUE;
245 size.height = CGFloat.max; //Float.MAX_VALUE; 344 size.height = CGFloat.max; //Float.MAX_VALUE;
246 textContainer.initWithContainerSize(size); 345 textContainer.initWithContainerSize(size);
247 textStorage.addLayoutManager(layoutManager); 346 textStorage.addLayoutManager(layoutManager);
248 layoutManager.addTextContainer(textContainer); 347 layoutManager.addTextContainer(textContainer);
249 NSRange range = NSRange(); 348 NSRange range = NSRange();
250 range.length = str.length(); 349 range.length = str.length();
251 textStorage.beginEditing(); 350 textStorage.beginEditing();
252 textStorage.addAttribute(OS.NSFontAttributeName(), font.handle, range); 351 textStorage.addAttribute(OS.NSFontAttributeName, font.handle, range);
253 textStorage.endEditing(); 352 textStorage.endEditing();
254 range = layoutManager.glyphRangeForTextContainer(textContainer); 353 range = layoutManager.glyphRangeForTextContainer(textContainer);
255 if (range.length !is 0) { 354 if (range.length !is 0) {
256 NSGlyph* glyphs = cast(NSGlyph*) OS.malloc(4 * range.length * 2); 355 NSGlyph* glyphs = cast(NSGlyph*) OS.malloc(4 * range.length * 2);
257 layoutManager.getGlyphs(glyphs, range); 356 layoutManager.getGlyphs(glyphs, range);
258 NSBezierPath path = NSBezierPath.bezierPath(); 357 NSBezierPath path = NSBezierPath.bezierPath();
259 NSPoint point = NSPoint(); 358 NSPoint point = NSPoint();
260 point.x = x; 359 point.x = x;
261 point.y = y; 360 point.y = y;
262 path.moveToPoint(point); 361 path.moveToPoint(point);
263 path.appendBezierPathWithGlyphs(glyphs, range.length, font.handle); 362 path.appendBezierPathWithGlyphs(glyphs, range.length, font.handle);
264 NSAffineTransform transform = NSAffineTransform.transform(); 363 NSAffineTransform transform = NSAffineTransform.transform();
265 transform.scaleXBy(1, -1); 364 transform.scaleXBy(1, -1);
266 transform.translateXBy(0, -((2*y) + textStorage.size().height)); 365 transform.translateXBy(0, -((2*y) + textStorage.size().height));
267 path.transformUsingAffineTransform(transform); 366 path.transformUsingAffineTransform(transform);
268 OS.free(glyphs); 367 OS.free(glyphs);
269 handle.appendBezierPath(path); 368 handle.appendBezierPath(path);
270 } 369 }
271 textContainer.release(); 370 textContainer.release();
272 layoutManager.release(); 371 layoutManager.release();
273 textStorage.release(); 372 textStorage.release();
373 } finally {
374 if (pool !is null) pool.release();
375 }
274 } 376 }
275 377
276 /** 378 /**
277 * Closes the current sub path by adding to the receiver a line 379 * Closes the current sub path by adding to the receiver a line
278 * from the current point of the path back to the starting point 380 * from the current point of the path back to the starting point
282 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 384 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
283 * </ul> 385 * </ul>
284 */ 386 */
285 public void close() { 387 public void close() {
286 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 388 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
287 handle.closePath(); 389 NSAutoreleasePool pool = null;
390 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
391 try {
392 handle.closePath();
393 } finally {
394 if (pool !is null) pool.release();
395 }
288 } 396 }
289 397
290 /** 398 /**
291 * Returns <code>true</code> if the specified point is contained by 399 * Returns <code>true</code> if the specified point is contained by
292 * the receiver and false otherwise. 400 * the receiver and false otherwise.
312 */ 420 */
313 public bool contains(float x, float y, GC gc, bool outline) { 421 public bool contains(float x, float y, GC gc, bool outline) {
314 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 422 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
315 if (gc is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); 423 if (gc is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
316 if (gc.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); 424 if (gc.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
317 // gc.checkGC(GC.LINE_CAP | GC.LINE_JOIN | GC.LINE_STYLE | GC.LINE_WIDTH); 425 NSAutoreleasePool pool = null;
318 //TODO outline 426 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
427 try {
428 // gc.checkGC(GC.LINE_CAP | GC.LINE_JOIN | GC.LINE_STYLE | GC.LINE_WIDTH);
429 //TODO outline
319 NSPoint point = NSPoint(); 430 NSPoint point = NSPoint();
320 point.x = x; 431 point.x = x;
321 point.y = y; 432 point.y = y;
322 return handle.containsPoint(point); 433 return handle.containsPoint(point);
434 } finally {
435 if (pool !is null) pool.release();
436 }
323 } 437 }
324 438
325 /** 439 /**
326 * Adds to the receiver a cubic bezier curve based on the parameters. 440 * Adds to the receiver a cubic bezier curve based on the parameters.
327 * 441 *
336 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 450 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
337 * </ul> 451 * </ul>
338 */ 452 */
339 public void cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y) { 453 public void cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y) {
340 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 454 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
341 NSPoint pt = NSPoint(); 455 NSAutoreleasePool pool = null;
342 pt.x = x; 456 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
343 pt.y = y; 457 try {
458 NSPoint pt = NSPoint();
459 pt.x = x;
460 pt.y = y;
344 NSPoint ct1 = NSPoint(); 461 NSPoint ct1 = NSPoint();
345 ct1.x = cx1; 462 ct1.x = cx1;
346 ct1.y = cy1; 463 ct1.y = cy1;
347 NSPoint ct2 = NSPoint(); 464 NSPoint ct2 = NSPoint();
348 ct2.x = cx2; 465 ct2.x = cx2;
349 ct2.y = cy2; 466 ct2.y = cy2;
350 handle.curveToPoint(pt, ct1, ct2); 467 handle.curveToPoint(pt, ct1, ct2);
468 } finally {
469 if (pool !is null) pool.release();
470 }
351 } 471 }
352 472
353 void destroy() { 473 void destroy() {
354 handle.release(); 474 handle.release();
355 handle = null; 475 handle = null;
372 */ 492 */
373 public void getBounds(float[] bounds) { 493 public void getBounds(float[] bounds) {
374 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 494 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
375 if (bounds is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); 495 if (bounds is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
376 if (bounds.length < 4) DWT.error(DWT.ERROR_INVALID_ARGUMENT); 496 if (bounds.length < 4) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
377 NSRect rect = handle.controlPointBounds(); 497 NSAutoreleasePool pool = null;
378 bounds[0] = rect.x; 498 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
379 bounds[1] = rect.y; 499 try {
380 bounds[2] = rect.width; 500 NSRect rect = handle.controlPointBounds();
381 bounds[3] = rect.height; 501 bounds[0] = (float)/*64*/rect.x;
502 bounds[1] = (float)/*64*/rect.y;
503 bounds[2] = (float)/*64*/rect.width;
504 bounds[3] = (float)/*64*/rect.height;
505 } finally {
506 if (pool !is null) pool.release();
507 }
382 } 508 }
383 509
384 /** 510 /**
385 * Replaces the first two elements in the parameter with values that 511 * Replaces the first two elements in the parameter with values that
386 * describe the current point of the path. 512 * describe the current point of the path.
397 */ 523 */
398 public void getCurrentPoint(float[] point) { 524 public void getCurrentPoint(float[] point) {
399 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 525 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
400 if (point is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); 526 if (point is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
401 if (point.length < 2) DWT.error(DWT.ERROR_INVALID_ARGUMENT); 527 if (point.length < 2) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
402 NSPoint pt = handle.currentPoint(); 528 NSAutoreleasePool pool = null;
403 point[0] = pt.x; 529 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
404 point[1] = pt.y; 530 try {
531 NSPoint pt = handle.currentPoint();
532 point[0] = (float)/*64*/pt.x;
533 point[1] = (float)/*64*/pt.y;
534 } finally {
535 if (pool !is null) pool.release();
536 }
405 } 537 }
406 538
407 /** 539 /**
408 * Returns a device independent representation of the receiver. 540 * Returns a device independent representation of the receiver.
409 * 541 *
415 * 547 *
416 * @see PathData 548 * @see PathData
417 */ 549 */
418 public PathData getPathData() { 550 public PathData getPathData() {
419 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 551 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
420 int count = handle.elementCount(); 552 NSAutoreleasePool pool = null;
421 int pointCount = 0, typeCount = 0; 553 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
422 byte[] types = new byte[count]; 554 try {
423 float[] pointArray = new float[count * 6]; 555 int count = (int)/*64*/handle.elementCount();
556 int pointCount = 0, typeCount = 0;
557 byte[] types = new byte[count];
558 float[] pointArray = new float[count * 6];
424 NSPointArray points = cast(NSPointArray) OS.malloc(3 * NSPoint.sizeof); 559 NSPointArray points = cast(NSPointArray) OS.malloc(3 * NSPoint.sizeof);
425 if (points is null) DWT.error(DWT.ERROR_NO_HANDLES); 560 if (points is null) DWT.error(DWT.ERROR_NO_HANDLES);
426 NSPoint pt = NSPoint(); 561 NSPoint pt = NSPoint();
427 for (NSInteger i = 0; i < count; i++) { 562 for (NSInteger i = 0; i < count; i++) {
428 NSBezierPathElement element = handle.elementAtIndex_associatedPoints_(i, points); 563 NSBezierPathElement element = handle.elementAtIndex(i, points);
429 switch (element) { 564 switch (element) {
430 case NSMoveToBezierPathElement: 565 case NSMoveToBezierPathElement:
431 types[typeCount++] = DWT.PATH_MOVE_TO; 566 types[typeCount++] = DWT.PATH_MOVE_TO;
432 OS.memmove(&pt, points, NSPoint.sizeof); 567 OS.memmove(&pt, points, NSPoint.sizeof);
433 pointArray[pointCount++] = cast(int)pt.x; 568 pointArray[pointCount++] = cast(int)pt.x;
434 pointArray[pointCount++] = cast(int)pt.y; 569 pointArray[pointCount++] = cast(int)pt.y;
435 break; 570 break;
436 case NSLineToBezierPathElement: 571 case NSLineToBezierPathElement:
437 types[typeCount++] = DWT.PATH_LINE_TO; 572 types[typeCount++] = DWT.PATH_LINE_TO;
438 OS.memmove(&pt, points, NSPoint.sizeof); 573 OS.memmove(&pt, points, NSPoint.sizeof);
439 pointArray[pointCount++] = cast(int)pt.x; 574 pointArray[pointCount++] = cast(int)pt.x;
440 pointArray[pointCount++] = cast(int)pt.y; 575 pointArray[pointCount++] = cast(int)pt.y;
441 break; 576 break;
442 case NSCurveToBezierPathElement: 577 case NSCurveToBezierPathElement:
443 types[typeCount++] = DWT.PATH_CUBIC_TO; 578 types[typeCount++] = DWT.PATH_CUBIC_TO;
444 OS.memmove(&pt, points, NSPoint.sizeof); 579 OS.memmove(&pt, points, NSPoint.sizeof);
445 pointArray[pointCount++] = cast(int)pt.x; 580 pointArray[pointCount++] = cast(int)pt.x;
446 pointArray[pointCount++] = cast(int)pt.y; 581 pointArray[pointCount++] = cast(int)pt.y;
447 OS.memmove(&pt, points + NSPoint.sizeof, NSPoint.sizeof); 582 OS.memmove(&pt, points + NSPoint.sizeof, NSPoint.sizeof);
448 pointArray[pointCount++] = cast(int)pt.x; 583 pointArray[pointCount++] = cast(int)pt.x;
449 pointArray[pointCount++] = cast(int)pt.y; 584 pointArray[pointCount++] = cast(int)pt.y;
450 OS.memmove(&pt, points + NSPoint.sizeof + NSPoint.sizeof, NSPoint.sizeof); 585 OS.memmove(&pt, points + NSPoint.sizeof + NSPoint.sizeof, NSPoint.sizeof);
451 pointArray[pointCount++] = cast(int)pt.x; 586 pointArray[pointCount++] = cast(int)pt.x;
452 pointArray[pointCount++] = cast(int)pt.y; 587 pointArray[pointCount++] = cast(int)pt.y;
453 break; 588 break;
454 case NSClosePathBezierPathElement: 589 case NSClosePathBezierPathElement:
455 types[typeCount++] = DWT.PATH_CLOSE; 590 types[typeCount++] = DWT.PATH_CLOSE;
456 break; 591 break;
592 }
457 } 593 }
458 } 594 OS.free(points);
459 OS.free(points); 595 if (pointCount !is pointArray.length) {
460 if (pointCount !is pointArray.length) { 596 float[] temp = new float[pointCount];
461 float[] temp = new float[pointCount]; 597 System.arraycopy(pointArray, 0, temp, 0, pointCount);
462 System.arraycopy(pointArray, 0, temp, 0, pointCount); 598 pointArray = temp;
463 pointArray = temp; 599 }
464 } 600 PathData data = new PathData();
465 PathData data = new PathData(); 601 data.types = types;
466 data.types = types; 602 data.points = pointArray;
467 data.points = pointArray; 603 return data;
468 return data; 604 } finally {
605 if (pool !is null) pool.release();
606 }
469 } 607 }
470 608
471 void init_(PathData data) { 609 void init_(PathData data) {
472 byte[] types = data.types; 610 byte[] types = data.types;
473 float[] points = data.points; 611 float[] points = data.points;
520 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 658 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
521 * </ul> 659 * </ul>
522 */ 660 */
523 public void lineTo(float x, float y) { 661 public void lineTo(float x, float y) {
524 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 662 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
525 NSPoint pt = NSPoint(); 663 NSAutoreleasePool pool = null;
526 pt.x = x; 664 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
527 pt.y = y; 665 try {
528 handle.lineToPoint(pt); 666 NSPoint pt = NSPoint();
667 pt.x = x;
668 pt.y = y;
669 handle.lineToPoint(pt);
670 } finally {
671 if (pool !is null) pool.release();
672 }
529 } 673 }
530 674
531 /** 675 /**
532 * Sets the current point of the receiver to the point 676 * Sets the current point of the receiver to the point
533 * specified by (x, y). Note that this starts a new 677 * specified by (x, y). Note that this starts a new
540 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 684 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
541 * </ul> 685 * </ul>
542 */ 686 */
543 public void moveTo(float x, float y) { 687 public void moveTo(float x, float y) {
544 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 688 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
545 NSPoint pt = NSPoint(); 689 NSAutoreleasePool pool = null;
546 pt.x = x; 690 if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init();
547 pt.y = y; 691 try {
548 handle.moveToPoint(pt); 692 NSPoint pt = NSPoint();
549 693 pt.x = x;
694 pt.y = y;
695 handle.moveToPoint(pt);
696 } finally {
697 if (pool !is null) pool.release();
698 }
550 } 699 }
551 700
552 /** 701 /**
553 * Adds to the receiver a quadratic curve based on the parameters. 702 * Adds to the receiver a quadratic curve based on the parameters.
554 * 703 *
561 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 710 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
562 * </ul> 711 * </ul>
563 */ 712 */
564 public void quadTo(float cx, float cy, float x, float y) { 713 public void quadTo(float cx, float cy, float x, float y) {
565 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 714 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
566 NSPoint pt = NSPoint(); 715 NSAutoreleasePool pool = null;
567 pt.x = x; 716 if (!NSThread.isMainThread()) pool = cast(NSAutoreleasePool) (new NSAutoreleasePool()).alloc().init();
568 pt.y = y; 717 try {
718 NSPoint pt = NSPoint();
719 pt.x = x;
720 pt.y = y;
569 NSPoint ct = NSPoint(); 721 NSPoint ct = NSPoint();
570 ct.x = cx; 722 ct.x = cx;
571 ct.y = cy; 723 ct.y = cy;
572 handle.curveToPoint(pt, ct, ct); 724 handle.curveToPoint(pt, ct, ct);
725 } finally {
726 if (pool !is null) pool.release();
727 }
573 } 728 }
574 729
575 /** 730 /**
576 * Returns a string containing a concise, human-readable 731 * Returns a string containing a concise, human-readable
577 * description of the receiver. 732 * description of the receiver.