comparison dwt/graphics/Path.d @ 34:5123b17c98ef

Ported dwt.events.*, dwt.graphics.GC, Region, dwt.internal.image.*
author Jacob Carlborg <doob@me.com> <jacob.carlborg@gmail.com>
date Sun, 14 Sep 2008 01:45:57 +0200
parents e831403a80a9
children db5a898b2119
comparison
equal deleted inserted replaced
33:965ac0a77267 34:5123b17c98ef
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 *
11 * Port to the D programming language:
12 * Jacob Carlborg <jacob.carlborg@gmail.com>
10 *******************************************************************************/ 13 *******************************************************************************/
11 module dwt.graphics.Path; 14 module dwt.graphics.Path;
12 15
13 import dwt.dwthelper.utils;
14 16
15 import dwt.DWT; 17 import dwt.DWT;
16 import dwt.DWTError; 18 import dwt.DWTError;
17 import dwt.DWTException; 19 import dwt.DWTException;
18 import dwt.internal.cocoa.NSAffineTransform; 20 import dwt.internal.cocoa.NSAffineTransform;
25 import dwt.internal.cocoa.NSString; 27 import dwt.internal.cocoa.NSString;
26 import dwt.internal.cocoa.NSTextContainer; 28 import dwt.internal.cocoa.NSTextContainer;
27 import dwt.internal.cocoa.NSTextStorage; 29 import dwt.internal.cocoa.NSTextStorage;
28 import dwt.internal.cocoa.OS; 30 import dwt.internal.cocoa.OS;
29 31
32 import tango.text.convert.Format;
33
34 import dwt.dwthelper.utils;
35 import dwt.graphics.Device;
36 import dwt.graphics.Font;
37 import dwt.graphics.GC;
38 import dwt.graphics.GCData;
39 import dwt.graphics.PathData;
40 import dwt.graphics.Resource;
41 import dwt.internal.cocoa.CGFloat;
42 import dwt.internal.cocoa.NSFont : NSGlyph;
43
30 /** 44 /**
31 * Instances of this class represent paths through the two-dimensional 45 * Instances of this class represent paths through the two-dimensional
32 * coordinate system. Paths do not have to be continuous, and can be 46 * coordinate system. Paths do not have to be continuous, and can be
33 * described using lines, rectangles, arcs, cubic or quadratic bezier curves, 47 * described using lines, rectangles, arcs, cubic or quadratic bezier curves,
34 * glyphs, or other paths. 48 * glyphs, or other paths.
83 public this (Device device) { 97 public this (Device device) {
84 super(device); 98 super(device);
85 handle = NSBezierPath.bezierPath(); 99 handle = NSBezierPath.bezierPath();
86 if (handle is null) DWT.error(DWT.ERROR_NO_HANDLES); 100 if (handle is null) DWT.error(DWT.ERROR_NO_HANDLES);
87 handle.retain(); 101 handle.retain();
88 handle.moveToPoint(new NSPoint()); 102 handle.moveToPoint(NSPoint());
89 init(); 103 init();
90 } 104 }
91 105
92 public this (Device device, Path path, float flatness) { 106 public this (Device device, Path path, float flatness) {
93 super(device); 107 super(device);
94 if (path is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); 108 if (path is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
95 if (path.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); 109 if (path.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
96 flatness = Math.max(0, flatness); 110 flatness = Math.max(0, flatness);
97 if (flatness is 0) { 111 if (flatness is 0) {
98 handle = new NSBezierPath(path.handle.copy().id); 112 handle = new NSBezierPath(path.handle.copy().id_);
99 } else { 113 } else {
100 float defaultFlatness = NSBezierPath.defaultFlatness(); 114 CGFloat defaultFlatness = NSBezierPath.defaultFlatness();
101 NSBezierPath.setDefaultFlatness(flatness); 115 NSBezierPath.setDefaultFlatness(flatness);
102 handle = path.handle.bezierPathByFlatteningPath(); 116 handle = path.handle.bezierPathByFlatteningPath();
103 NSBezierPath.setDefaultFlatness(defaultFlatness); 117 NSBezierPath.setDefaultFlatness(defaultFlatness);
104 } 118 }
105 if (handle is null) DWT.error(DWT.ERROR_NO_HANDLES); 119 if (handle is null) DWT.error(DWT.ERROR_NO_HANDLES);
145 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 159 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
146 NSAffineTransform transform = NSAffineTransform.transform(); 160 NSAffineTransform transform = NSAffineTransform.transform();
147 transform.translateXBy(x + width / 2f, y + height / 2f); 161 transform.translateXBy(x + width / 2f, y + height / 2f);
148 transform.scaleXBy(width / 2f, height / 2f); 162 transform.scaleXBy(width / 2f, height / 2f);
149 NSBezierPath path = NSBezierPath.bezierPath(); 163 NSBezierPath path = NSBezierPath.bezierPath();
150 NSPoint center = new NSPoint(); 164 NSPoint center = NSPoint();
151 float sAngle = -startAngle; 165 CGFloat sAngle = -startAngle;
152 float eAngle = -(startAngle + arcAngle); 166 CGFloat eAngle = -(startAngle + arcAngle);
153 path.appendBezierPathWithArcWithCenter_radius_startAngle_endAngle_clockwise_(center, 1, sAngle, eAngle, arcAngle>0); 167 path.appendBezierPathWithArcWithCenter_radius_startAngle_endAngle_clockwise_(center, 1, sAngle, eAngle, arcAngle>0);
154 path.transformUsingAffineTransform(transform); 168 path.transformUsingAffineTransform(transform);
155 handle.appendBezierPath(path); 169 handle.appendBezierPath(path);
156 } 170 }
157 171
187 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 201 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
188 * </ul> 202 * </ul>
189 */ 203 */
190 public void addRectangle(float x, float y, float width, float height) { 204 public void addRectangle(float x, float y, float width, float height) {
191 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 205 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
192 NSRect rect = new NSRect(); 206 NSRect rect = NSRect();
193 rect.x = x; 207 rect.x = x;
194 rect.y = y; 208 rect.y = y;
195 rect.width = width; 209 rect.width = width;
196 rect.height = height; 210 rect.height = height;
197 handle.appendBezierPathWithRect(rect); 211 handle.appendBezierPathWithRect(rect);
199 213
200 /** 214 /**
201 * Adds to the receiver the pattern of glyphs generated by drawing 215 * Adds to the receiver the pattern of glyphs generated by drawing
202 * the given string using the given font starting at the point (x, y). 216 * the given string using the given font starting at the point (x, y).
203 * 217 *
204 * @param string the text to use 218 * @param stri the text to use
205 * @param x the x coordinate of the starting point 219 * @param x the x coordinate of the starting point
206 * @param y the y coordinate of the starting point 220 * @param y the y coordinate of the starting point
207 * @param font the font to use 221 * @param font the font to use
208 * 222 *
209 * @exception IllegalArgumentException <ul> 223 * @exception IllegalArgumentException <ul>
212 * </ul> 226 * </ul>
213 * @exception DWTException <ul> 227 * @exception DWTException <ul>
214 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 228 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
215 * </ul> 229 * </ul>
216 */ 230 */
217 public void addString(String string, float x, float y, Font font) { 231 public void addString(String stri, float x, float y, Font font) {
218 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 232 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
219 if (font is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); 233 if (font is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
220 if (font.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); 234 if (font.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
221 NSString str = NSString.stringWith(string); 235 NSString str = NSString.stringWith(stri);
222 NSTextStorage textStorage = (cast(NSTextStorage)new NSTextStorage().alloc()); 236 NSTextStorage textStorage = (cast(NSTextStorage)(new NSTextStorage()).alloc());
223 textStorage.initWithString_(str); 237 textStorage.initWithString_(str);
224 NSLayoutManager layoutManager = cast(NSLayoutManager)new NSLayoutManager().alloc().init(); 238 NSLayoutManager layoutManager = cast(NSLayoutManager)(new NSLayoutManager()).alloc().init();
225 NSTextContainer textContainer = cast(NSTextContainer)new NSTextContainer().alloc(); 239 NSTextContainer textContainer = cast(NSTextContainer)(new NSTextContainer()).alloc();
226 NSSize size = new NSSize(); 240 NSSize size = NSSize();
227 size.width = Float.MAX_VALUE; 241 size.width = CGFloat.max; //Float.MAX_VALUE;
228 size.height = Float.MAX_VALUE; 242 size.height = CGFloat.max; //Float.MAX_VALUE;
229 textContainer.initWithContainerSize(size); 243 textContainer.initWithContainerSize(size);
230 textStorage.addLayoutManager(layoutManager); 244 textStorage.addLayoutManager(layoutManager);
231 layoutManager.addTextContainer(textContainer); 245 layoutManager.addTextContainer(textContainer);
232 NSRange range = new NSRange(); 246 NSRange range = NSRange();
233 range.length = str.length(); 247 range.length = str.length();
234 textStorage.beginEditing(); 248 textStorage.beginEditing();
235 textStorage.addAttribute(OS.NSFontAttributeName(), font.handle, range); 249 textStorage.addAttribute(OS.NSFontAttributeName(), font.handle, range);
236 textStorage.endEditing(); 250 textStorage.endEditing();
237 range = layoutManager.glyphRangeForTextContainer(textContainer); 251 range = layoutManager.glyphRangeForTextContainer(textContainer);
238 if (range.length !is 0) { 252 if (range.length !is 0) {
239 int glyphs = OS.malloc(4 * range.length * 2); 253 NSGlyph* glyphs = OS.malloc(4 * range.length * 2);
240 layoutManager.getGlyphs(glyphs, range); 254 layoutManager.getGlyphs(glyphs, range);
241 NSBezierPath path = NSBezierPath.bezierPath(); 255 NSBezierPath path = NSBezierPath.bezierPath();
242 NSPoint point = new NSPoint(); 256 NSPoint point = NSPoint();
243 point.x = x; 257 point.x = x;
244 point.y = y; 258 point.y = y;
245 path.moveToPoint(point); 259 path.moveToPoint(point);
246 path.appendBezierPathWithGlyphs(glyphs, range.length, font.handle); 260 path.appendBezierPathWithGlyphs(glyphs, range.length, font.handle);
247 NSAffineTransform transform = NSAffineTransform.transform(); 261 NSAffineTransform transform = NSAffineTransform.transform();
297 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 311 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
298 if (gc is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); 312 if (gc is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
299 if (gc.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); 313 if (gc.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
300 // gc.checkGC(GC.LINE_CAP | GC.LINE_JOIN | GC.LINE_STYLE | GC.LINE_WIDTH); 314 // gc.checkGC(GC.LINE_CAP | GC.LINE_JOIN | GC.LINE_STYLE | GC.LINE_WIDTH);
301 //TODO outline 315 //TODO outline
302 NSPoint point = new NSPoint(); 316 NSPoint point = NSPoint();
303 point.x = x; 317 point.x = x;
304 point.y = y; 318 point.y = y;
305 return handle.containsPoint(point); 319 return handle.containsPoint(point);
306 } 320 }
307 321
319 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 333 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
320 * </ul> 334 * </ul>
321 */ 335 */
322 public void cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y) { 336 public void cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y) {
323 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 337 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
324 NSPoint pt = new NSPoint(); 338 NSPoint pt = NSPoint();
325 pt.x = x; 339 pt.x = x;
326 pt.y = y; 340 pt.y = y;
327 NSPoint ct1 = new NSPoint(); 341 NSPoint ct1 = NSPoint();
328 ct1.x = cx1; 342 ct1.x = cx1;
329 ct1.y = cy1; 343 ct1.y = cy1;
330 NSPoint ct2 = new NSPoint(); 344 NSPoint ct2 = NSPoint();
331 ct2.x = cx2; 345 ct2.x = cx2;
332 ct2.y = cy2; 346 ct2.y = cy2;
333 handle.curveToPoint(pt, ct1, ct2); 347 handle.curveToPoint(pt, ct1, ct2);
334 } 348 }
335 349
402 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 416 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
403 int count = handle.elementCount(); 417 int count = handle.elementCount();
404 int pointCount = 0, typeCount = 0; 418 int pointCount = 0, typeCount = 0;
405 byte[] types = new byte[count]; 419 byte[] types = new byte[count];
406 float[] pointArray = new float[count * 6]; 420 float[] pointArray = new float[count * 6];
407 int points = OS.malloc(3 * NSPoint.sizeof); 421 NSPointArray points = OS.malloc(3 * NSPoint.sizeof);
408 if (points is 0) DWT.error(DWT.ERROR_NO_HANDLES); 422 if (points is 0) DWT.error(DWT.ERROR_NO_HANDLES);
409 NSPoint pt = new NSPoint(); 423 NSPoint pt = NSPoint();
410 for (int i = 0; i < count; i++) { 424 for (NSInteger i = 0; i < count; i++) {
411 int element = handle.elementAtIndex_associatedPoints_(i, points); 425 NSBezierPathElement element = handle.elementAtIndex_associatedPoints_(i, points);
412 switch (element) { 426 switch (element) {
413 case OS.NSMoveToBezierPathElement: 427 case OS.NSMoveToBezierPathElement:
414 types[typeCount++] = DWT.PATH_MOVE_TO; 428 types[typeCount++] = DWT.PATH_MOVE_TO;
415 OS.memmove(pt, points, NSPoint.sizeof); 429 OS.memmove(pt, points, NSPoint.sizeof);
416 pointArray[pointCount++] = cast(int)pt.x; 430 pointArray[pointCount++] = cast(int)pt.x;
503 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 517 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
504 * </ul> 518 * </ul>
505 */ 519 */
506 public void lineTo(float x, float y) { 520 public void lineTo(float x, float y) {
507 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 521 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
508 NSPoint pt = new NSPoint(); 522 NSPoint pt = NSPoint();
509 pt.x = x; 523 pt.x = x;
510 pt.y = y; 524 pt.y = y;
511 handle.lineToPoint(pt); 525 handle.lineToPoint(pt);
512 } 526 }
513 527
523 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 537 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
524 * </ul> 538 * </ul>
525 */ 539 */
526 public void moveTo(float x, float y) { 540 public void moveTo(float x, float y) {
527 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 541 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
528 NSPoint pt = new NSPoint(); 542 NSPoint pt = NSPoint();
529 pt.x = x; 543 pt.x = x;
530 pt.y = y; 544 pt.y = y;
531 handle.moveToPoint(pt); 545 handle.moveToPoint(pt);
532 546
533 } 547 }
544 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 558 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
545 * </ul> 559 * </ul>
546 */ 560 */
547 public void quadTo(float cx, float cy, float x, float y) { 561 public void quadTo(float cx, float cy, float x, float y) {
548 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 562 if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
549 NSPoint pt = new NSPoint(); 563 NSPoint pt = NSPoint();
550 pt.x = x; 564 pt.x = x;
551 pt.y = y; 565 pt.y = y;
552 NSPoint ct = new NSPoint(); 566 NSPoint ct = NSPoint();
553 ct.x = cx; 567 ct.x = cx;
554 ct.y = cy; 568 ct.y = cy;
555 handle.curveToPoint(pt, ct, ct); 569 handle.curveToPoint(pt, ct, ct);
556 } 570 }
557 571
561 * 575 *
562 * @return a string representation of the receiver 576 * @return a string representation of the receiver
563 */ 577 */
564 public String toString () { 578 public String toString () {
565 if (isDisposed()) return "Path {*DISPOSED*}"; 579 if (isDisposed()) return "Path {*DISPOSED*}";
566 return "Path {" + handle + "}"; 580 return Format("Path {{}{}" , handle , "}");
567 } 581 }
568 582
569 } 583 }