Mercurial > projects > dwt-mac
comparison dwt/graphics/GC.d @ 0:380af2bdd8e5
Upload of whole dwt tree
author | Jacob Carlborg <doob@me.com> <jacob.carlborg@gmail.com> |
---|---|
date | Sat, 09 Aug 2008 17:00:02 +0200 |
parents | |
children | 649b8e223d5a |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:380af2bdd8e5 |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2000, 2007 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 *******************************************************************************/ | |
11 module dwt.graphics.GC; | |
12 | |
13 import dwt.dwthelper.utils; | |
14 | |
15 import dwt.DWT; | |
16 import dwt.DWTError; | |
17 import dwt.DWTException; | |
18 import dwt.internal.cocoa.NSAffineTransform; | |
19 import dwt.internal.cocoa.NSAffineTransformStruct; | |
20 import dwt.internal.cocoa.NSAttributedString; | |
21 import dwt.internal.cocoa.NSBezierPath; | |
22 import dwt.internal.cocoa.NSColor; | |
23 import dwt.internal.cocoa.NSFont; | |
24 import dwt.internal.cocoa.NSGradient; | |
25 import dwt.internal.cocoa.NSGraphicsContext; | |
26 import dwt.internal.cocoa.NSImage; | |
27 import dwt.internal.cocoa.NSMutableDictionary; | |
28 import dwt.internal.cocoa.NSPoint; | |
29 import dwt.internal.cocoa.NSRect; | |
30 import dwt.internal.cocoa.NSSize; | |
31 import dwt.internal.cocoa.NSString; | |
32 import dwt.internal.cocoa.OS; | |
33 | |
34 /** | |
35 * Class <code>GC</code> is where all of the drawing capabilities that are | |
36 * supported by DWT are located. Instances are used to draw on either an | |
37 * <code>Image</code>, a <code>Control</code>, or directly on a <code>Display</code>. | |
38 * <dl> | |
39 * <dt><b>Styles:</b></dt> | |
40 * <dd>LEFT_TO_RIGHT, RIGHT_TO_LEFT</dd> | |
41 * </dl> | |
42 * | |
43 * <p> | |
44 * The DWT drawing coordinate system is the two-dimensional space with the origin | |
45 * (0,0) at the top left corner of the drawing area and with (x,y) values increasing | |
46 * to the right and downward respectively. | |
47 * </p> | |
48 * | |
49 * <p> | |
50 * Application code must explicitly invoke the <code>GC.dispose()</code> | |
51 * method to release the operating system resources managed by each instance | |
52 * when those instances are no longer required. This is <em>particularly</em> | |
53 * important on Windows95 and Windows98 where the operating system has a limited | |
54 * number of device contexts available. | |
55 * </p> | |
56 * | |
57 * <p> | |
58 * Note: Only one of LEFT_TO_RIGHT and RIGHT_TO_LEFT may be specified. | |
59 * </p> | |
60 * | |
61 * @see dwt.events.PaintEvent | |
62 */ | |
63 public final class GC extends Resource { | |
64 /** | |
65 * the handle to the OS device context | |
66 * (Warning: This field is platform dependent) | |
67 * <p> | |
68 * <b>IMPORTANT:</b> This field is <em>not</em> part of the DWT | |
69 * public API. It is marked public only so that it can be shared | |
70 * within the packages provided by DWT. It is not available on all | |
71 * platforms and should never be accessed from application code. | |
72 * </p> | |
73 */ | |
74 public NSGraphicsContext handle; | |
75 | |
76 Drawable drawable; | |
77 GCData data; | |
78 | |
79 static final int TAB_COUNT = 32; | |
80 | |
81 final static int FOREGROUND = 1 << 0; | |
82 final static int BACKGROUND = 1 << 1; | |
83 final static int FONT = 1 << 2; | |
84 final static int LINE_STYLE = 1 << 3; | |
85 final static int LINE_CAP = 1 << 4; | |
86 final static int LINE_JOIN = 1 << 5; | |
87 final static int LINE_WIDTH = 1 << 6; | |
88 final static int LINE_MITERLIMIT = 1 << 7; | |
89 final static int FOREGROUND_FILL = 1 << 8; | |
90 final static int DRAW_OFFSET = 1 << 9; | |
91 final static int CLIPPING = 1 << 10; | |
92 final static int TRANSFORM = 1 << 11; | |
93 final static int DRAW = CLIPPING | TRANSFORM | FOREGROUND | LINE_WIDTH | LINE_STYLE | LINE_CAP | LINE_JOIN | LINE_MITERLIMIT | DRAW_OFFSET; | |
94 final static int FILL = CLIPPING | TRANSFORM | BACKGROUND; | |
95 | |
96 static final float[] LINE_DOT = new float[]{1, 1}; | |
97 static final float[] LINE_DASH = new float[]{3, 1}; | |
98 static final float[] LINE_DASHDOT = new float[]{3, 1, 1, 1}; | |
99 static final float[] LINE_DASHDOTDOT = new float[]{3, 1, 1, 1, 1, 1}; | |
100 static final float[] LINE_DOT_ZERO = new float[]{3, 3}; | |
101 static final float[] LINE_DASH_ZERO = new float[]{18, 6}; | |
102 static final float[] LINE_DASHDOT_ZERO = new float[]{9, 6, 3, 6}; | |
103 static final float[] LINE_DASHDOTDOT_ZERO = new float[]{9, 3, 3, 3, 3, 3}; | |
104 | |
105 GC() { | |
106 } | |
107 | |
108 /** | |
109 * Constructs a new instance of this class which has been | |
110 * configured to draw on the specified drawable. Sets the | |
111 * foreground color, background color and font in the GC | |
112 * to match those in the drawable. | |
113 * <p> | |
114 * You must dispose the graphics context when it is no longer required. | |
115 * </p> | |
116 * @param drawable the drawable to draw on | |
117 * @exception IllegalArgumentException <ul> | |
118 * <li>ERROR_NULL_ARGUMENT - if the drawable is null</li> | |
119 * <li>ERROR_NULL_ARGUMENT - if there is no current device</li> | |
120 * <li>ERROR_INVALID_ARGUMENT | |
121 * - if the drawable is an image that is not a bitmap or an icon | |
122 * - if the drawable is an image or printer that is already selected | |
123 * into another graphics context</li> | |
124 * </ul> | |
125 * @exception DWTError <ul> | |
126 * <li>ERROR_NO_HANDLES if a handle could not be obtained for GC creation</li> | |
127 * <li>ERROR_THREAD_INVALID_ACCESS if not called from the thread that created the drawable</li> | |
128 * </ul> | |
129 */ | |
130 public GC(Drawable drawable) { | |
131 this(drawable, 0); | |
132 } | |
133 | |
134 /** | |
135 * Constructs a new instance of this class which has been | |
136 * configured to draw on the specified drawable. Sets the | |
137 * foreground color, background color and font in the GC | |
138 * to match those in the drawable. | |
139 * <p> | |
140 * You must dispose the graphics context when it is no longer required. | |
141 * </p> | |
142 * | |
143 * @param drawable the drawable to draw on | |
144 * @param style the style of GC to construct | |
145 * | |
146 * @exception IllegalArgumentException <ul> | |
147 * <li>ERROR_NULL_ARGUMENT - if the drawable is null</li> | |
148 * <li>ERROR_NULL_ARGUMENT - if there is no current device</li> | |
149 * <li>ERROR_INVALID_ARGUMENT | |
150 * - if the drawable is an image that is not a bitmap or an icon | |
151 * - if the drawable is an image or printer that is already selected | |
152 * into another graphics context</li> | |
153 * </ul> | |
154 * @exception DWTError <ul> | |
155 * <li>ERROR_NO_HANDLES if a handle could not be obtained for GC creation</li> | |
156 * <li>ERROR_THREAD_INVALID_ACCESS if not called from the thread that created the drawable</li> | |
157 * </ul> | |
158 * | |
159 * @since 2.1.2 | |
160 */ | |
161 public GC(Drawable drawable, int style) { | |
162 if (drawable is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | |
163 GCData data = new GCData(); | |
164 data.style = checkStyle(style); | |
165 int contextId = drawable.internal_new_GC(data); | |
166 Device device = data.device; | |
167 if (device is null) device = Device.getDevice(); | |
168 if (device is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | |
169 this.device = data.device = device; | |
170 init(drawable, data, contextId); | |
171 init(); | |
172 } | |
173 | |
174 static int checkStyle (int style) { | |
175 if ((style & DWT.LEFT_TO_RIGHT) !is 0) style &= ~DWT.RIGHT_TO_LEFT; | |
176 return style & (DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT); | |
177 } | |
178 | |
179 /** | |
180 * Invokes platform specific functionality to allocate a new graphics context. | |
181 * <p> | |
182 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public | |
183 * API for <code>GC</code>. It is marked public only so that it | |
184 * can be shared within the packages provided by DWT. It is not | |
185 * available on all platforms, and should never be called from | |
186 * application code. | |
187 * </p> | |
188 * | |
189 * @param drawable the Drawable for the receiver. | |
190 * @param data the data for the receiver. | |
191 * | |
192 * @return a new <code>GC</code> | |
193 * | |
194 * @private | |
195 */ | |
196 public static GC cocoa_new(Drawable drawable, GCData data) { | |
197 GC gc = new GC(); | |
198 int context = drawable.internal_new_GC(data); | |
199 gc.device = data.device; | |
200 gc.init(drawable, data, context); | |
201 return gc; | |
202 } | |
203 | |
204 /** | |
205 * Invokes platform specific functionality to wrap a graphics context. | |
206 * <p> | |
207 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public | |
208 * API for <code>GC</code>. It is marked public only so that it | |
209 * can be shared within the packages provided by DWT. It is not | |
210 * available on all platforms, and should never be called from | |
211 * application code. | |
212 * </p> | |
213 * | |
214 * @param context the Quartz context. | |
215 * @param data the data for the receiver. | |
216 * | |
217 * @return a new <code>GC</code> | |
218 */ | |
219 public static GC carbon_new(int context, GCData data) { | |
220 GC gc = new GC(); | |
221 gc.device = data.device; | |
222 gc.init(null, data, context); | |
223 return gc; | |
224 } | |
225 | |
226 void checkGC (int mask) { | |
227 if ((data.state & CLIPPING) is 0 || (data.state & TRANSFORM) is 0) { | |
228 handle.restoreGraphicsState(); | |
229 handle.saveGraphicsState(); | |
230 if (data.clipPath !is null) data.clipPath.addClip(); | |
231 if (data.transform !is null) data.transform.concat(); | |
232 mask &= ~(TRANSFORM | CLIPPING); | |
233 data.state |= TRANSFORM | CLIPPING; | |
234 data.state &= ~(BACKGROUND | FOREGROUND); | |
235 } | |
236 | |
237 int state = data.state; | |
238 if ((state & mask) is mask) return; | |
239 state = (state ^ mask) & mask; | |
240 data.state |= mask; | |
241 | |
242 if ((state & FOREGROUND) !is 0) { | |
243 Pattern pattern = data.foregroundPattern; | |
244 if (pattern !is null) { | |
245 if (pattern.color !is null) pattern.color.setStroke(); | |
246 } else { | |
247 float[] color = data.foreground; | |
248 NSColor.colorWithDeviceRed(color[0], color[1], color[2], data.alpha / 255f).setStroke(); | |
249 } | |
250 } | |
251 if ((state & FOREGROUND_FILL) !is 0) { | |
252 Pattern pattern = data.foregroundPattern; | |
253 if (pattern !is null) { | |
254 if (pattern.color !is null) pattern.color.setFill(); | |
255 } else { | |
256 float[] color = data.foreground; | |
257 NSColor.colorWithDeviceRed(color[0], color[1], color[2], data.alpha / 255f).setFill(); | |
258 } | |
259 data.state &= ~BACKGROUND; | |
260 } | |
261 if ((state & BACKGROUND) !is 0) { | |
262 Pattern pattern = data.backgroundPattern; | |
263 if (pattern !is null) { | |
264 if (pattern.color !is null) pattern.color.setFill(); | |
265 } else { | |
266 float[] color = data.background; | |
267 NSColor.colorWithDeviceRed(color[0], color[1], color[2], data.alpha / 255f).setFill(); | |
268 } | |
269 data.state &= ~FOREGROUND_FILL; | |
270 } | |
271 NSBezierPath path = data.path; | |
272 if ((state & LINE_WIDTH) !is 0) { | |
273 path.setLineWidth(data.lineWidth is 0 ? 1 : data.lineWidth); | |
274 switch (data.lineStyle) { | |
275 case DWT.LINE_DOT: | |
276 case DWT.LINE_DASH: | |
277 case DWT.LINE_DASHDOT: | |
278 case DWT.LINE_DASHDOTDOT: | |
279 state |= LINE_STYLE; | |
280 } | |
281 } | |
282 if ((state & LINE_STYLE) !is 0) { | |
283 float[] dashes = null; | |
284 float width = data.lineWidth; | |
285 switch (data.lineStyle) { | |
286 case DWT.LINE_SOLID: break; | |
287 case DWT.LINE_DASH: dashes = width !is 0 ? LINE_DASH : LINE_DASH_ZERO; break; | |
288 case DWT.LINE_DOT: dashes = width !is 0 ? LINE_DOT : LINE_DOT_ZERO; break; | |
289 case DWT.LINE_DASHDOT: dashes = width !is 0 ? LINE_DASHDOT : LINE_DASHDOT_ZERO; break; | |
290 case DWT.LINE_DASHDOTDOT: dashes = width !is 0 ? LINE_DASHDOTDOT : LINE_DASHDOTDOT_ZERO; break; | |
291 case DWT.LINE_CUSTOM: dashes = data.lineDashes; break; | |
292 } | |
293 if (dashes !is null) { | |
294 float[] lengths = new float[dashes.length]; | |
295 for (int i = 0; i < lengths.length; i++) { | |
296 lengths[i] = width is 0 || data.lineStyle is DWT.LINE_CUSTOM ? dashes[i] : dashes[i] * width; | |
297 } | |
298 path.setLineDash(lengths, lengths.length, data.lineDashesOffset); | |
299 } else { | |
300 path.setLineDash(null, 0, 0); | |
301 } | |
302 } | |
303 if ((state & LINE_MITERLIMIT) !is 0) { | |
304 path.setMiterLimit(data.lineMiterLimit); | |
305 } | |
306 if ((state & LINE_JOIN) !is 0) { | |
307 int joinStyle = 0; | |
308 switch (data.lineJoin) { | |
309 case DWT.JOIN_MITER: joinStyle = OS.NSMiterLineJoinStyle; break; | |
310 case DWT.JOIN_ROUND: joinStyle = OS.NSRoundLineJoinStyle; break; | |
311 case DWT.JOIN_BEVEL: joinStyle = OS.NSBevelLineJoinStyle; break; | |
312 } | |
313 path.setLineJoinStyle(joinStyle); | |
314 } | |
315 if ((state & LINE_CAP) !is 0) { | |
316 int capStyle = 0; | |
317 switch (data.lineCap) { | |
318 case DWT.CAP_ROUND: capStyle = OS.NSRoundLineCapStyle; break; | |
319 case DWT.CAP_FLAT: capStyle = OS.NSButtLineCapStyle; break; | |
320 case DWT.CAP_SQUARE: capStyle = OS.NSSquareLineCapStyle; break; | |
321 } | |
322 path.setLineCapStyle(capStyle); | |
323 } | |
324 if ((state & DRAW_OFFSET) !is 0) { | |
325 data.drawXOffset = data.drawYOffset = 0; | |
326 NSSize size = new NSSize(); | |
327 size.width = size.height = 1; | |
328 if (data.transform !is null) { | |
329 size = data.transform.transformSize(size); | |
330 } | |
331 float scaling = size.width; | |
332 if (scaling < 0) scaling = -scaling; | |
333 float strokeWidth = data.lineWidth * scaling; | |
334 if (strokeWidth is 0 || ((int)strokeWidth % 2) is 1) { | |
335 data.drawXOffset = 0.5f / scaling; | |
336 } | |
337 scaling = size.height; | |
338 if (scaling < 0) scaling = -scaling; | |
339 strokeWidth = data.lineWidth * scaling; | |
340 if (strokeWidth is 0 || ((int)strokeWidth % 2) is 1) { | |
341 data.drawYOffset = 0.5f / scaling; | |
342 } | |
343 } | |
344 } | |
345 | |
346 /** | |
347 * Copies a rectangular area of the receiver at the specified | |
348 * position into the image, which must be of type <code>DWT.BITMAP</code>. | |
349 * | |
350 * @param image the image to copy into | |
351 * @param x the x coordinate in the receiver of the area to be copied | |
352 * @param y the y coordinate in the receiver of the area to be copied | |
353 * | |
354 * @exception IllegalArgumentException <ul> | |
355 * <li>ERROR_NULL_ARGUMENT - if the image is null</li> | |
356 * <li>ERROR_INVALID_ARGUMENT - if the image is not a bitmap or has been disposed</li> | |
357 * </ul> | |
358 * @exception DWTException <ul> | |
359 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
360 * </ul> | |
361 */ | |
362 public void copyArea(Image image, int x, int y) { | |
363 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
364 if (image is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | |
365 if (image.type !is DWT.BITMAP || image.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
366 // if (data.image !is null) { | |
367 // copyArea(image, x, y, data.image.handle); | |
368 // } else if (data.control !is 0) { | |
369 // int imageHandle = image.handle; | |
370 // int width = OS.CGImageGetWidth(imageHandle); | |
371 // int height = OS.CGImageGetHeight(imageHandle); | |
372 // int window = OS.GetControlOwner(data.control); | |
373 // Rect srcRect = new Rect (); | |
374 // CGPoint pt = new CGPoint (); | |
375 // int[] contentView = new int[1]; | |
376 // OS.HIViewFindByID(OS.HIViewGetRoot(window), OS.kHIViewWindowContentID(), contentView); | |
377 // OS.HIViewConvertPoint (pt, data.control, contentView[0]); | |
378 // x += (int) pt.x; | |
379 // y += (int) pt.y; | |
380 // Rect inset = data.insetRect; | |
381 // x -= inset.left; | |
382 // y -= inset.top; | |
383 // srcRect.left = (short)x; | |
384 // srcRect.top = (short)y; | |
385 // srcRect.right = (short)(x + width); | |
386 // srcRect.bottom = (short)(y + height); | |
387 // Rect destRect = new Rect(); | |
388 // destRect.right = (short)width; | |
389 // destRect.bottom = (short)height; | |
390 // int bpl = width * 4; | |
391 // int[] gWorld = new int[1]; | |
392 // int port = OS.GetWindowPort(window); | |
393 // OS.NewGWorldFromPtr(gWorld, OS.k32ARGBPixelFormat, destRect, 0, 0, 0, image.data, bpl); | |
394 // OS.CopyBits(OS.GetPortBitMapForCopyBits(port), OS.GetPortBitMapForCopyBits(gWorld[0]), srcRect, destRect, (short)OS.srcCopy, 0); | |
395 // OS.DisposeGWorld(gWorld [0]); | |
396 // } else if (data.window !is 0) { | |
397 // int imageHandle = image.handle; | |
398 // CGRect rect = new CGRect(); | |
399 // rect.x = x; | |
400 // rect.y = y; | |
401 // rect.width = OS.CGImageGetWidth(imageHandle); | |
402 // rect.height = OS.CGImageGetHeight(imageHandle); | |
403 // int[] displays = new int[16]; | |
404 // int[] count = new int[1]; | |
405 // if (OS.CGGetDisplaysWithRect(rect, displays.length, displays, count) !is 0) return; | |
406 // for (int i = 0; i < count[0]; i++) { | |
407 // int display = displays[i]; | |
408 // int address = OS.CGDisplayBaseAddress(display); | |
409 // if (address !is 0) { | |
410 // int width = OS.CGDisplayPixelsWide(display); | |
411 // int height = OS.CGDisplayPixelsHigh(display); | |
412 // int bpr = OS.CGDisplayBytesPerRow(display); | |
413 // int bpp = OS.CGDisplayBitsPerPixel(display); | |
414 // int bps = OS.CGDisplayBitsPerSample(display); | |
415 // int bitmapInfo = OS.kCGImageAlphaNoneSkipFirst; | |
416 // switch (bpp) { | |
417 // case 16: bitmapInfo |= OS.kCGBitmapByteOrder16Host; break; | |
418 // case 32: bitmapInfo |= OS.kCGBitmapByteOrder32Host; break; | |
419 // } | |
420 // int srcImage = 0; | |
421 // if (OS.__BIG_ENDIAN__() && OS.VERSION >= 0x1040) { | |
422 // int context = OS.CGBitmapContextCreate(address, width, height, bps, bpr, data.device.colorspace, bitmapInfo); | |
423 // srcImage = OS.CGBitmapContextCreateImage(context); | |
424 // OS.CGContextRelease(context); | |
425 // } else { | |
426 // int provider = OS.CGDataProviderCreateWithData(0, address, bpr * height, 0); | |
427 // srcImage = OS.CGImageCreate(width, height, bps, bpp, bpr, data.device.colorspace, bitmapInfo, provider, null, true, 0); | |
428 // OS.CGDataProviderRelease(provider); | |
429 // } | |
430 // copyArea(image, x, y, srcImage); | |
431 // if (srcImage !is 0) OS.CGImageRelease(srcImage); | |
432 // } | |
433 // } | |
434 // } | |
435 } | |
436 | |
437 void copyArea (Image image, int x, int y, int srcImage) { | |
438 if (srcImage is 0) return; | |
439 // int imageHandle = image.handle; | |
440 // int bpc = OS.CGImageGetBitsPerComponent(imageHandle); | |
441 // int width = OS.CGImageGetWidth(imageHandle); | |
442 // int height = OS.CGImageGetHeight(imageHandle); | |
443 // int bpr = OS.CGImageGetBytesPerRow(imageHandle); | |
444 // int alphaInfo = OS.CGImageGetAlphaInfo(imageHandle); | |
445 // int context = OS.CGBitmapContextCreate(image.data, width, height, bpc, bpr, data.device.colorspace, alphaInfo); | |
446 // if (context !is 0) { | |
447 // CGRect rect = new CGRect(); | |
448 // rect.x = -x; | |
449 // rect.y = y; | |
450 // rect.width = OS.CGImageGetWidth(srcImage); | |
451 // rect.height = OS.CGImageGetHeight(srcImage); | |
452 // OS.CGContextTranslateCTM(context, 0, -(rect.height - height)); | |
453 // OS.CGContextDrawImage(context, rect, srcImage); | |
454 // OS.CGContextRelease(context); | |
455 // } | |
456 } | |
457 | |
458 /** | |
459 * Copies a rectangular area of the receiver at the source | |
460 * position onto the receiver at the destination position. | |
461 * | |
462 * @param srcX the x coordinate in the receiver of the area to be copied | |
463 * @param srcY the y coordinate in the receiver of the area to be copied | |
464 * @param width the width of the area to copy | |
465 * @param height the height of the area to copy | |
466 * @param destX the x coordinate in the receiver of the area to copy to | |
467 * @param destY the y coordinate in the receiver of the area to copy to | |
468 * | |
469 * @exception DWTException <ul> | |
470 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
471 * </ul> | |
472 */ | |
473 public void copyArea(int srcX, int srcY, int width, int height, int destX, int destY) { | |
474 copyArea(srcX, srcY, width, height, destX, destY, true); | |
475 } | |
476 /** | |
477 * Copies a rectangular area of the receiver at the source | |
478 * position onto the receiver at the destination position. | |
479 * | |
480 * @param srcX the x coordinate in the receiver of the area to be copied | |
481 * @param srcY the y coordinate in the receiver of the area to be copied | |
482 * @param width the width of the area to copy | |
483 * @param height the height of the area to copy | |
484 * @param destX the x coordinate in the receiver of the area to copy to | |
485 * @param destY the y coordinate in the receiver of the area to copy to | |
486 * @param paint if <code>true</code> paint events will be generated for old and obscured areas | |
487 * | |
488 * @exception DWTException <ul> | |
489 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
490 * </ul> | |
491 * | |
492 * @since 3.1 | |
493 */ | |
494 public void copyArea(int srcX, int srcY, int width, int height, int destX, int destY, bool paint) { | |
495 // if (handle is 0) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
496 // if (data.updateClip) setCGClipping(); | |
497 // if (width <= 0 || height <= 0) return; | |
498 // int deltaX = destX - srcX, deltaY = destY - srcY; | |
499 // if (deltaX is 0 && deltaY is 0) return; | |
500 // if (data.image !is null) { | |
501 // OS.CGContextSaveGState(handle); | |
502 // OS.CGContextScaleCTM(handle, 1, -1); | |
503 // OS.CGContextTranslateCTM(handle, 0, -(height + 2 * destY)); | |
504 // CGRect rect = new CGRect(); | |
505 // rect.x = destX; | |
506 // rect.y = destY; | |
507 // rect.width = width; | |
508 // rect.height = height; | |
509 // int h = OS.CGImageGetHeight(data.image.handle); | |
510 // int bpr = OS.CGImageGetBytesPerRow(data.image.handle); | |
511 // int provider = OS.CGDataProviderCreateWithData(0, data.image.data, bpr * h, 0); | |
512 // if (provider !is 0) { | |
513 // int colorspace = device.colorspace; | |
514 // int img = OS.CGImageCreate(width, height, 8, 32, bpr, colorspace, OS.kCGImageAlphaNoneSkipFirst, provider, null, true, 0); | |
515 // OS.CGDataProviderRelease(provider); | |
516 // OS.CGContextDrawImage(handle, rect, img); | |
517 // OS.CGImageRelease(img); | |
518 // } | |
519 // OS.CGContextRestoreGState(handle); | |
520 // return; | |
521 // } | |
522 // if (data.control !is 0) { | |
523 // int port = data.port; | |
524 // int window = OS.GetControlOwner(data.control); | |
525 // if (port is 0) port = OS.GetWindowPort(window); | |
526 // | |
527 // /* Calculate src and dest rectangles/regions */ | |
528 // Rect rect = new Rect(); | |
529 // OS.GetControlBounds(data.control, rect); | |
530 // int convertX = 0, convertY = 0; | |
531 // CGPoint pt = new CGPoint (); | |
532 // int[] contentView = new int[1]; | |
533 // OS.HIViewFindByID(OS.HIViewGetRoot(window), OS.kHIViewWindowContentID(), contentView); | |
534 // OS.HIViewConvertPoint(pt, OS.HIViewGetSuperview(data.control), contentView[0]); | |
535 // convertX = rect.left + (int) pt.x; | |
536 // convertY = rect.top + (int) pt.y; | |
537 // rect.left += (int) pt.x; | |
538 // rect.top += (int) pt.y; | |
539 // rect.right += (int) pt.x; | |
540 // rect.bottom += (int) pt.y; | |
541 // Rect srcRect = new Rect(); | |
542 // int left = rect.left + srcX; | |
543 // int top = rect.top + srcY; | |
544 // OS.SetRect(srcRect, (short)left, (short)top, (short)(left + width), (short)(top + height)); | |
545 // int srcRgn = OS.NewRgn(); | |
546 // OS.RectRgn(srcRgn, srcRect); | |
547 // OS.SectRect(rect, srcRect, srcRect); | |
548 // Rect destRect = new Rect (); | |
549 // OS.SetRect(destRect, srcRect.left, srcRect.top, srcRect.right, srcRect.bottom); | |
550 // OS.OffsetRect(destRect, (short)deltaX, (short)deltaY); | |
551 // int destRgn = OS.NewRgn(); | |
552 // OS.RectRgn(destRgn, destRect); | |
553 // | |
554 // /* Copy bits with appropriated clipping region */ | |
555 // if (!OS.EmptyRect(srcRect)) { | |
556 // if (data.visibleRgn is 0 || OS.RectInRgn(srcRect, data.visibleRgn)) { | |
557 // int clipRgn = data.visibleRgn; | |
558 // if (data.clipRgn !is 0) { | |
559 // clipRgn = OS.NewRgn(); | |
560 // OS.SectRgn(data.clipRgn, data.visibleRgn, clipRgn); | |
561 // } | |
562 // | |
563 // /* | |
564 // * Feature in the Macintosh. ScrollRect() only copies bits | |
565 // * that are inside the specified rectangle. This means that | |
566 // * it is not possible to copy non overlaping bits without | |
567 // * copying the bits in between the source and destination | |
568 // * rectangles. The fix is to check if the source and | |
569 // * destination rectangles are disjoint and use CopyBits() | |
570 // * instead. | |
571 // */ | |
572 // if (!OS.EmptyRgn(clipRgn)) { | |
573 // bool disjoint = (destX + width < srcX) || (srcX + width < destX) || (destY + height < srcY) || (srcY + height < destY); | |
574 // if (!disjoint && (deltaX is 0 || deltaY is 0)) { | |
575 // int[] currentPort = new int[1]; | |
576 // OS.GetPort(currentPort); | |
577 // OS.SetPort(port); | |
578 // int oldClip = OS.NewRgn(); | |
579 // OS.GetClip(oldClip); | |
580 // OS.SetClip(clipRgn); | |
581 // OS.UnionRect(srcRect, destRect, rect); | |
582 // OS.ScrollRect(rect, (short)deltaX, (short)deltaY, 0); | |
583 // OS.SetClip(oldClip); | |
584 // OS.DisposeRgn(oldClip); | |
585 // OS.SetPort(currentPort[0]); | |
586 // } else { | |
587 // int portBitMap = OS.GetPortBitMapForCopyBits (port); | |
588 // OS.CopyBits(portBitMap, portBitMap, srcRect, destRect, (short)OS.srcCopy, clipRgn); | |
589 // OS.QDFlushPortBuffer(port, destRgn); | |
590 // } | |
591 // } | |
592 // | |
593 // if (clipRgn !is data.visibleRgn) OS.DisposeRgn(clipRgn); | |
594 // } | |
595 // } | |
596 // | |
597 // /* Invalidate src and obscured areas */ | |
598 // if (paint) { | |
599 // int invalRgn = OS.NewRgn(); | |
600 // OS.DiffRgn(srcRgn, data.visibleRgn, invalRgn); | |
601 // OS.OffsetRgn(invalRgn, (short)deltaX, (short)deltaY); | |
602 // OS.DiffRgn(srcRgn, destRgn, srcRgn); | |
603 // OS.UnionRgn(srcRgn, invalRgn, invalRgn); | |
604 // OS.SectRgn(data.visibleRgn, invalRgn, invalRgn); | |
605 // OS.OffsetRgn(invalRgn, (short)-convertX, (short)-convertY); | |
606 // OS.HIViewSetNeedsDisplayInRegion(data.control, invalRgn, true); | |
607 // OS.DisposeRgn(invalRgn); | |
608 // } | |
609 // | |
610 // /* Dispose src and dest regions */ | |
611 // OS.DisposeRgn(destRgn); | |
612 // OS.DisposeRgn(srcRgn); | |
613 // } | |
614 } | |
615 | |
616 NSAttributedString createString(String string, int flags) { | |
617 NSMutableDictionary dict = NSMutableDictionary.dictionaryWithCapacity(4); | |
618 float[] foreground = data.foreground; | |
619 NSColor color = NSColor.colorWithDeviceRed(foreground[0], foreground[1], foreground[2], data.alpha / 255f); | |
620 dict.setObject(color, OS.NSForegroundColorAttributeName()); | |
621 dict.setObject(data.font.handle, OS.NSFontAttributeName()); | |
622 if ((flags & DWT.DRAW_TRANSPARENT) is 0) { | |
623 float[] background = data.background; | |
624 color = NSColor.colorWithDeviceRed(background[0], background[1], background[2], data.alpha / 255f); | |
625 dict.setObject(color, OS.NSBackgroundColorAttributeName()); | |
626 } | |
627 int length = string.length(); | |
628 char[] chars = new char[length]; | |
629 string.getChars(0, length, chars, 0); | |
630 // int breakCount = 0; | |
631 // int[] breaks = null; | |
632 // if ((flags & (DWT.DRAW_MNEMONIC | DWT.DRAW_DELIMITER)) !is 0) { | |
633 // int i=0, j=0; | |
634 // while (i < chars.length) { | |
635 // char c = chars [j++] = chars [i++]; | |
636 // switch (c) { | |
637 // case '&': { | |
638 // if ((flags & DWT.DRAW_MNEMONIC) !is 0) { | |
639 // if (i is chars.length) {continue;} | |
640 // if (chars [i] is '&') {i++; continue;} | |
641 // j--; | |
642 // } | |
643 // break; | |
644 // } | |
645 // case '\r': | |
646 // case '\n': { | |
647 // if ((flags & DWT.DRAW_DELIMITER) !is 0) { | |
648 // if (c is '\r' && i !is chars.length && chars[i] is '\n') i++; | |
649 // j--; | |
650 // if (breaks is null) { | |
651 // breaks = new int[4]; | |
652 // } else if (breakCount is breaks.length) { | |
653 // int[] newBreaks = new int[breaks.length + 4]; | |
654 // System.arraycopy(breaks, 0, newBreaks, 0, breaks.length); | |
655 // breaks = newBreaks; | |
656 // } | |
657 // breaks[breakCount++] = j; | |
658 // } | |
659 // break; | |
660 // } | |
661 // } | |
662 // } | |
663 // length = j; | |
664 // } | |
665 NSString str = NSString.stringWithCharacters(chars, length); | |
666 return ((NSAttributedString)new NSAttributedString().alloc()).initWithString_attributes_(str, dict); | |
667 } | |
668 | |
669 void destroy() { | |
670 /* Free resources */ | |
671 Image image = data.image; | |
672 if (image !is null) { | |
673 image.memGC = null; | |
674 image.createAlpha(); | |
675 } | |
676 if (data.clipPath !is null) data.clipPath.release(); | |
677 if (data.transform !is null) data.transform.release(); | |
678 if (data.inverseTransform !is null) data.inverseTransform.release(); | |
679 data.path = data.clipPath = null; | |
680 data.transform = data.inverseTransform = null; | |
681 | |
682 /* Dispose the GC */ | |
683 if (drawable !is null) drawable.internal_dispose_GC(handle.id, data); | |
684 handle.restoreGraphicsState(); | |
685 handle.release(); | |
686 | |
687 drawable = null; | |
688 data.image = null; | |
689 data = null; | |
690 handle = null; | |
691 } | |
692 | |
693 /** | |
694 * Draws the outline of a circular or elliptical arc | |
695 * within the specified rectangular area. | |
696 * <p> | |
697 * The resulting arc begins at <code>startAngle</code> and extends | |
698 * for <code>arcAngle</code> degrees, using the current color. | |
699 * Angles are interpreted such that 0 degrees is at the 3 o'clock | |
700 * position. A positive value indicates a counter-clockwise rotation | |
701 * while a negative value indicates a clockwise rotation. | |
702 * </p><p> | |
703 * The center of the arc is the center of the rectangle whose origin | |
704 * is (<code>x</code>, <code>y</code>) and whose size is specified by the | |
705 * <code>width</code> and <code>height</code> arguments. | |
706 * </p><p> | |
707 * The resulting arc covers an area <code>width + 1</code> pixels wide | |
708 * by <code>height + 1</code> pixels tall. | |
709 * </p> | |
710 * | |
711 * @param x the x coordinate of the upper-left corner of the arc to be drawn | |
712 * @param y the y coordinate of the upper-left corner of the arc to be drawn | |
713 * @param width the width of the arc to be drawn | |
714 * @param height the height of the arc to be drawn | |
715 * @param startAngle the beginning angle | |
716 * @param arcAngle the angular extent of the arc, relative to the start angle | |
717 * | |
718 * @exception DWTException <ul> | |
719 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
720 * </ul> | |
721 */ | |
722 public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) { | |
723 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
724 NSGraphicsContext context = NSGraphicsContext.currentContext(); | |
725 NSGraphicsContext.setCurrentContext(handle); | |
726 checkGC(DRAW); | |
727 if (width < 0) { | |
728 x = x + width; | |
729 width = -width; | |
730 } | |
731 if (height < 0) { | |
732 y = y + height; | |
733 height = -height; | |
734 } | |
735 if (width is 0 || height is 0 || arcAngle is 0) return; | |
736 handle.saveGraphicsState(); | |
737 NSAffineTransform transform = NSAffineTransform.transform(); | |
738 float xOffset = data.drawXOffset, yOffset = data.drawYOffset; | |
739 transform.translateXBy(x + xOffset + width / 2f, y + yOffset + height / 2f); | |
740 transform.scaleXBy(width / 2f, height / 2f); | |
741 NSBezierPath path = data.path; | |
742 NSPoint center = new NSPoint(); | |
743 float sAngle = -startAngle; | |
744 float eAngle = -(startAngle + arcAngle); | |
745 path.appendBezierPathWithArcWithCenter_radius_startAngle_endAngle_clockwise_(center, 1, sAngle, eAngle, arcAngle>0); | |
746 path.transformUsingAffineTransform(transform); | |
747 path.stroke(); | |
748 path.removeAllPoints(); | |
749 handle.restoreGraphicsState(); | |
750 NSGraphicsContext.setCurrentContext(context); | |
751 } | |
752 | |
753 /** | |
754 * Draws a rectangle, based on the specified arguments, which has | |
755 * the appearance of the platform's <em>focus rectangle</em> if the | |
756 * platform supports such a notion, and otherwise draws a simple | |
757 * rectangle in the receiver's foreground color. | |
758 * | |
759 * @param x the x coordinate of the rectangle | |
760 * @param y the y coordinate of the rectangle | |
761 * @param width the width of the rectangle | |
762 * @param height the height of the rectangle | |
763 * | |
764 * @exception DWTException <ul> | |
765 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
766 * </ul> | |
767 * | |
768 * @see #drawRectangle(int, int, int, int) | |
769 */ | |
770 public void drawFocus(int x, int y, int width, int height) { | |
771 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
772 NSGraphicsContext context = NSGraphicsContext.currentContext(); | |
773 NSGraphicsContext.setCurrentContext(handle); | |
774 checkGC(CLIPPING | TRANSFORM); | |
775 // int[] metric = new int[1]; | |
776 // OS.GetThemeMetric(OS.kThemeMetricFocusRectOutset, metric); | |
777 // CGRect rect = new CGRect (); | |
778 // rect.x = x + metric[0]; | |
779 // rect.y = y + metric[0]; | |
780 // rect.width = width - metric[0] * 2; | |
781 // rect.height = height - metric[0] * 2; | |
782 // OS.HIThemeDrawFocusRect(rect, true, handle, OS.kHIThemeOrientationNormal); | |
783 // flush(); | |
784 NSGraphicsContext.setCurrentContext(context); | |
785 } | |
786 | |
787 /** | |
788 * Draws the given image in the receiver at the specified | |
789 * coordinates. | |
790 * | |
791 * @param image the image to draw | |
792 * @param x the x coordinate of where to draw | |
793 * @param y the y coordinate of where to draw | |
794 * | |
795 * @exception IllegalArgumentException <ul> | |
796 * <li>ERROR_NULL_ARGUMENT - if the image is null</li> | |
797 * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li> | |
798 * <li>ERROR_INVALID_ARGUMENT - if the given coordinates are outside the bounds of the image</li> | |
799 * @exception DWTException <ul> | |
800 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
801 * </ul> | |
802 * @exception DWTError <ul> | |
803 * <li>ERROR_NO_HANDLES - if no handles are available to perform the operation</li> | |
804 * </ul> | |
805 */ | |
806 public void drawImage(Image image, int x, int y) { | |
807 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
808 if (image is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | |
809 if (image.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
810 drawImage(image, 0, 0, -1, -1, x, y, -1, -1, true); | |
811 } | |
812 | |
813 /** | |
814 * Copies a rectangular area from the source image into a (potentially | |
815 * different sized) rectangular area in the receiver. If the source | |
816 * and destination areas are of differing sizes, then the source | |
817 * area will be stretched or shrunk to fit the destination area | |
818 * as it is copied. The copy fails if any part of the source rectangle | |
819 * lies outside the bounds of the source image, or if any of the width | |
820 * or height arguments are negative. | |
821 * | |
822 * @param image the source image | |
823 * @param srcX the x coordinate in the source image to copy from | |
824 * @param srcY the y coordinate in the source image to copy from | |
825 * @param srcWidth the width in pixels to copy from the source | |
826 * @param srcHeight the height in pixels to copy from the source | |
827 * @param destX the x coordinate in the destination to copy to | |
828 * @param destY the y coordinate in the destination to copy to | |
829 * @param destWidth the width in pixels of the destination rectangle | |
830 * @param destHeight the height in pixels of the destination rectangle | |
831 * | |
832 * @exception IllegalArgumentException <ul> | |
833 * <li>ERROR_NULL_ARGUMENT - if the image is null</li> | |
834 * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li> | |
835 * <li>ERROR_INVALID_ARGUMENT - if any of the width or height arguments are negative. | |
836 * <li>ERROR_INVALID_ARGUMENT - if the source rectangle is not contained within the bounds of the source image</li> | |
837 * </ul> | |
838 * @exception DWTException <ul> | |
839 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
840 * </ul> | |
841 * @exception DWTError <ul> | |
842 * <li>ERROR_NO_HANDLES - if no handles are available to perform the operation</li> | |
843 * </ul> | |
844 */ | |
845 public void drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight) { | |
846 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
847 if (srcWidth is 0 || srcHeight is 0 || destWidth is 0 || destHeight is 0) return; | |
848 if (srcX < 0 || srcY < 0 || srcWidth < 0 || srcHeight < 0 || destWidth < 0 || destHeight < 0) { | |
849 DWT.error (DWT.ERROR_INVALID_ARGUMENT); | |
850 } | |
851 if (image is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | |
852 if (image.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
853 drawImage(image, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, false); | |
854 } | |
855 | |
856 void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, bool simple) { | |
857 NSGraphicsContext context = NSGraphicsContext.currentContext(); | |
858 NSGraphicsContext.setCurrentContext(handle); | |
859 checkGC(CLIPPING | TRANSFORM); | |
860 NSImage imageHandle = srcImage.handle; | |
861 NSSize size = imageHandle.size(); | |
862 int imgWidth = (int)size.width; | |
863 int imgHeight = (int)size.height; | |
864 if (simple) { | |
865 srcWidth = destWidth = imgWidth; | |
866 srcHeight = destHeight = imgHeight; | |
867 } else { | |
868 simple = srcX is 0 && srcY is 0 && | |
869 srcWidth is destWidth && destWidth is imgWidth && | |
870 srcHeight is destHeight && destHeight is imgHeight; | |
871 if (srcX + srcWidth > imgWidth || srcY + srcHeight > imgHeight) { | |
872 NSGraphicsContext.setCurrentContext(context); | |
873 DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
874 } | |
875 } | |
876 if (srcImage.memGC !is null) srcImage.createAlpha(); | |
877 handle.saveGraphicsState(); | |
878 NSAffineTransform transform = NSAffineTransform.transform(); | |
879 transform.scaleXBy(1, -1); | |
880 transform.translateXBy(0, -(destHeight + 2 * destY)); | |
881 transform.concat(); | |
882 NSRect srcRect = new NSRect(); | |
883 srcRect.x = srcX; | |
884 srcRect.y = srcY; | |
885 srcRect.width = srcWidth; | |
886 srcRect.height = srcHeight; | |
887 NSRect destRect = new NSRect(); | |
888 destRect.x = destX; | |
889 destRect.y = destY; | |
890 destRect.width = destWidth; | |
891 destRect.height = destHeight; | |
892 imageHandle.drawInRect(destRect, srcRect, OS.NSCompositeSourceOver, 1); | |
893 handle.restoreGraphicsState(); | |
894 NSGraphicsContext.setCurrentContext(context); | |
895 } | |
896 | |
897 /** | |
898 * Draws a line, using the foreground color, between the points | |
899 * (<code>x1</code>, <code>y1</code>) and (<code>x2</code>, <code>y2</code>). | |
900 * | |
901 * @param x1 the first point's x coordinate | |
902 * @param y1 the first point's y coordinate | |
903 * @param x2 the second point's x coordinate | |
904 * @param y2 the second point's y coordinate | |
905 * | |
906 * @exception DWTException <ul> | |
907 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
908 * </ul> | |
909 */ | |
910 public void drawLine(int x1, int y1, int x2, int y2) { | |
911 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
912 NSGraphicsContext context = NSGraphicsContext.currentContext(); | |
913 NSGraphicsContext.setCurrentContext(handle); | |
914 checkGC(DRAW); | |
915 NSBezierPath path = data.path; | |
916 NSPoint pt = new NSPoint(); | |
917 pt.x = x1 + data.drawXOffset; | |
918 pt.y = y1 + data.drawYOffset; | |
919 path.moveToPoint(pt); | |
920 pt.x = x2 + data.drawXOffset; | |
921 pt.y = y2 + data.drawYOffset; | |
922 path.lineToPoint(pt); | |
923 path.stroke(); | |
924 path.removeAllPoints(); | |
925 NSGraphicsContext.setCurrentContext(context); | |
926 } | |
927 | |
928 /** | |
929 * Draws the outline of an oval, using the foreground color, | |
930 * within the specified rectangular area. | |
931 * <p> | |
932 * The result is a circle or ellipse that fits within the | |
933 * rectangle specified by the <code>x</code>, <code>y</code>, | |
934 * <code>width</code>, and <code>height</code> arguments. | |
935 * </p><p> | |
936 * The oval covers an area that is <code>width + 1</code> | |
937 * pixels wide and <code>height + 1</code> pixels tall. | |
938 * </p> | |
939 * | |
940 * @param x the x coordinate of the upper left corner of the oval to be drawn | |
941 * @param y the y coordinate of the upper left corner of the oval to be drawn | |
942 * @param width the width of the oval to be drawn | |
943 * @param height the height of the oval to be drawn | |
944 * | |
945 * @exception DWTException <ul> | |
946 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
947 * </ul> | |
948 */ | |
949 public void drawOval(int x, int y, int width, int height) { | |
950 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
951 NSGraphicsContext context = NSGraphicsContext.currentContext(); | |
952 NSGraphicsContext.setCurrentContext(handle); | |
953 checkGC(DRAW); | |
954 if (width < 0) { | |
955 x = x + width; | |
956 width = -width; | |
957 } | |
958 if (height < 0) { | |
959 y = y + height; | |
960 height = -height; | |
961 } | |
962 NSBezierPath path = data.path; | |
963 NSRect rect = new NSRect(); | |
964 rect.x = x + data.drawXOffset; | |
965 rect.y = y + data.drawXOffset; | |
966 rect.width = width; | |
967 rect.height = height; | |
968 path.appendBezierPathWithOvalInRect(rect); | |
969 path.stroke(); | |
970 path.removeAllPoints(); | |
971 NSGraphicsContext.setCurrentContext(context); | |
972 } | |
973 | |
974 /** | |
975 * Draws the path described by the parameter. | |
976 * <p> | |
977 * This operation requires the operating system's advanced | |
978 * graphics subsystem which may not be available on some | |
979 * platforms. | |
980 * </p> | |
981 * | |
982 * @param path the path to draw | |
983 * | |
984 * @exception IllegalArgumentException <ul> | |
985 * <li>ERROR_NULL_ARGUMENT - if the parameter is null</li> | |
986 * <li>ERROR_INVALID_ARGUMENT - if the parameter has been disposed</li> | |
987 * </ul> | |
988 * @exception DWTException <ul> | |
989 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
990 * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> | |
991 * </ul> | |
992 * | |
993 * @see Path | |
994 * | |
995 * @since 3.1 | |
996 */ | |
997 public void drawPath(Path path) { | |
998 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
999 if (path is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | |
1000 if (path.handle is null) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
1001 NSGraphicsContext context = NSGraphicsContext.currentContext(); | |
1002 NSGraphicsContext.setCurrentContext(handle); | |
1003 checkGC(DRAW); | |
1004 handle.saveGraphicsState(); | |
1005 NSAffineTransform transform = NSAffineTransform.transform(); | |
1006 transform.translateXBy(data.drawXOffset, data.drawYOffset); | |
1007 transform.concat(); | |
1008 NSBezierPath drawPath = data.path; | |
1009 drawPath.appendBezierPath(path.handle); | |
1010 drawPath.stroke(); | |
1011 drawPath.removeAllPoints(); | |
1012 handle.restoreGraphicsState(); | |
1013 NSGraphicsContext.setCurrentContext(context); | |
1014 } | |
1015 | |
1016 /** | |
1017 * Draws a pixel, using the foreground color, at the specified | |
1018 * point (<code>x</code>, <code>y</code>). | |
1019 * <p> | |
1020 * Note that the receiver's line attributes do not affect this | |
1021 * operation. | |
1022 * </p> | |
1023 * | |
1024 * @param x the point's x coordinate | |
1025 * @param y the point's y coordinate | |
1026 * | |
1027 * @exception DWTException <ul> | |
1028 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1029 * </ul> | |
1030 * | |
1031 * @since 3.0 | |
1032 */ | |
1033 public void drawPoint(int x, int y) { | |
1034 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1035 NSGraphicsContext context = NSGraphicsContext.currentContext(); | |
1036 NSGraphicsContext.setCurrentContext(handle); | |
1037 checkGC(FOREGROUND_FILL); | |
1038 NSRect rect = new NSRect(); | |
1039 rect.x = x; | |
1040 rect.y = y; | |
1041 rect.width = 1; | |
1042 rect.height = 1; | |
1043 NSBezierPath path = data.path; | |
1044 path.appendBezierPathWithRect(rect); | |
1045 path.fill(); | |
1046 path.removeAllPoints(); | |
1047 NSGraphicsContext.setCurrentContext(context); | |
1048 } | |
1049 | |
1050 /** | |
1051 * Draws the closed polygon which is defined by the specified array | |
1052 * of integer coordinates, using the receiver's foreground color. The array | |
1053 * contains alternating x and y values which are considered to represent | |
1054 * points which are the vertices of the polygon. Lines are drawn between | |
1055 * each consecutive pair, and between the first pair and last pair in the | |
1056 * array. | |
1057 * | |
1058 * @param pointArray an array of alternating x and y values which are the vertices of the polygon | |
1059 * | |
1060 * @exception IllegalArgumentException <ul> | |
1061 * <li>ERROR_NULL_ARGUMENT if pointArray is null</li> | |
1062 * </ul> | |
1063 * @exception DWTException <ul> | |
1064 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1065 * </ul> | |
1066 */ | |
1067 public void drawPolygon(int[] pointArray) { | |
1068 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1069 if (pointArray is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | |
1070 NSGraphicsContext context = NSGraphicsContext.currentContext(); | |
1071 NSGraphicsContext.setCurrentContext(handle); | |
1072 checkGC(DRAW); | |
1073 if (pointArray.length < 4) return; | |
1074 float xOffset = data.drawXOffset, yOffset = data.drawYOffset; | |
1075 NSBezierPath path = data.path; | |
1076 NSPoint pt = new NSPoint(); | |
1077 pt.x = pointArray[0] + xOffset; | |
1078 pt.y = pointArray[1] + yOffset; | |
1079 path.moveToPoint(pt); | |
1080 int end = pointArray.length / 2 * 2; | |
1081 for (int i = 2; i < end; i+=2) { | |
1082 pt.x = pointArray[i] + xOffset; | |
1083 pt.y = pointArray[i+1] + yOffset; | |
1084 path.lineToPoint(pt); | |
1085 } | |
1086 path.closePath(); | |
1087 path.stroke(); | |
1088 path.removeAllPoints(); | |
1089 NSGraphicsContext.setCurrentContext(context); | |
1090 } | |
1091 | |
1092 /** | |
1093 * Draws the polyline which is defined by the specified array | |
1094 * of integer coordinates, using the receiver's foreground color. The array | |
1095 * contains alternating x and y values which are considered to represent | |
1096 * points which are the corners of the polyline. Lines are drawn between | |
1097 * each consecutive pair, but not between the first pair and last pair in | |
1098 * the array. | |
1099 * | |
1100 * @param pointArray an array of alternating x and y values which are the corners of the polyline | |
1101 * | |
1102 * @exception IllegalArgumentException <ul> | |
1103 * <li>ERROR_NULL_ARGUMENT - if the point array is null</li> | |
1104 * </ul> | |
1105 * @exception DWTException <ul> | |
1106 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1107 * </ul> | |
1108 */ | |
1109 public void drawPolyline(int[] pointArray) { | |
1110 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1111 if (pointArray is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | |
1112 NSGraphicsContext context = NSGraphicsContext.currentContext(); | |
1113 NSGraphicsContext.setCurrentContext(handle); | |
1114 checkGC(DRAW); | |
1115 if (pointArray.length < 4) return; | |
1116 float xOffset = data.drawXOffset, yOffset = data.drawYOffset; | |
1117 NSBezierPath path = data.path; | |
1118 NSPoint pt = new NSPoint(); | |
1119 pt.x = pointArray[0] + xOffset; | |
1120 pt.y = pointArray[1] + yOffset; | |
1121 path.moveToPoint(pt); | |
1122 int end = pointArray.length / 2 * 2; | |
1123 for (int i = 2; i < end; i+=2) { | |
1124 pt.x = pointArray[i] + xOffset; | |
1125 pt.y = pointArray[i+1] + yOffset; | |
1126 path.lineToPoint(pt); | |
1127 } | |
1128 path.stroke(); | |
1129 path.removeAllPoints(); | |
1130 NSGraphicsContext.setCurrentContext(context); | |
1131 } | |
1132 | |
1133 /** | |
1134 * Draws the outline of the rectangle specified by the arguments, | |
1135 * using the receiver's foreground color. The left and right edges | |
1136 * of the rectangle are at <code>x</code> and <code>x + width</code>. | |
1137 * The top and bottom edges are at <code>y</code> and <code>y + height</code>. | |
1138 * | |
1139 * @param x the x coordinate of the rectangle to be drawn | |
1140 * @param y the y coordinate of the rectangle to be drawn | |
1141 * @param width the width of the rectangle to be drawn | |
1142 * @param height the height of the rectangle to be drawn | |
1143 * | |
1144 * @exception DWTException <ul> | |
1145 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1146 * </ul> | |
1147 */ | |
1148 public void drawRectangle(int x, int y, int width, int height) { | |
1149 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1150 NSGraphicsContext context = NSGraphicsContext.currentContext(); | |
1151 NSGraphicsContext.setCurrentContext(handle); | |
1152 checkGC(DRAW); | |
1153 if (width < 0) { | |
1154 x = x + width; | |
1155 width = -width; | |
1156 } | |
1157 if (height < 0) { | |
1158 y = y + height; | |
1159 height = -height; | |
1160 } | |
1161 NSRect rect = new NSRect(); | |
1162 rect.x = x + data.drawXOffset; | |
1163 rect.y = y + data.drawYOffset; | |
1164 rect.width = width; | |
1165 rect.height = height; | |
1166 NSBezierPath path = data.path; | |
1167 path.appendBezierPathWithRect(rect); | |
1168 path.stroke(); | |
1169 path.removeAllPoints(); | |
1170 NSGraphicsContext.setCurrentContext(context); | |
1171 } | |
1172 | |
1173 /** | |
1174 * Draws the outline of the specified rectangle, using the receiver's | |
1175 * foreground color. The left and right edges of the rectangle are at | |
1176 * <code>rect.x</code> and <code>rect.x + rect.width</code>. The top | |
1177 * and bottom edges are at <code>rect.y</code> and | |
1178 * <code>rect.y + rect.height</code>. | |
1179 * | |
1180 * @param rect the rectangle to draw | |
1181 * | |
1182 * @exception IllegalArgumentException <ul> | |
1183 * <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li> | |
1184 * </ul> | |
1185 * @exception DWTException <ul> | |
1186 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1187 * </ul> | |
1188 */ | |
1189 public void drawRectangle(Rectangle rect) { | |
1190 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1191 if (rect is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | |
1192 drawRectangle (rect.x, rect.y, rect.width, rect.height); | |
1193 } | |
1194 | |
1195 /** | |
1196 * Draws the outline of the round-cornered rectangle specified by | |
1197 * the arguments, using the receiver's foreground color. The left and | |
1198 * right edges of the rectangle are at <code>x</code> and <code>x + width</code>. | |
1199 * The top and bottom edges are at <code>y</code> and <code>y + height</code>. | |
1200 * The <em>roundness</em> of the corners is specified by the | |
1201 * <code>arcWidth</code> and <code>arcHeight</code> arguments, which | |
1202 * are respectively the width and height of the ellipse used to draw | |
1203 * the corners. | |
1204 * | |
1205 * @param x the x coordinate of the rectangle to be drawn | |
1206 * @param y the y coordinate of the rectangle to be drawn | |
1207 * @param width the width of the rectangle to be drawn | |
1208 * @param height the height of the rectangle to be drawn | |
1209 * @param arcWidth the width of the arc | |
1210 * @param arcHeight the height of the arc | |
1211 * | |
1212 * @exception DWTException <ul> | |
1213 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1214 * </ul> | |
1215 */ | |
1216 public void drawRoundRectangle(int x, int y, int width, int height, int arcWidth, int arcHeight) { | |
1217 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1218 NSGraphicsContext context = NSGraphicsContext.currentContext(); | |
1219 NSGraphicsContext.setCurrentContext(handle); | |
1220 checkGC(DRAW); | |
1221 if (arcWidth is 0 || arcHeight is 0) { | |
1222 drawRectangle(x, y, width, height); | |
1223 NSGraphicsContext.setCurrentContext(context); | |
1224 return; | |
1225 } | |
1226 NSBezierPath path = data.path; | |
1227 NSRect rect = new NSRect(); | |
1228 rect.x = x + data.drawXOffset; | |
1229 rect.y = y + data.drawYOffset; | |
1230 rect.width = width; | |
1231 rect.height = height; | |
1232 path.appendBezierPathWithRoundedRect(rect, arcWidth, arcHeight); | |
1233 path.stroke(); | |
1234 path.removeAllPoints(); | |
1235 NSGraphicsContext.setCurrentContext(context); | |
1236 } | |
1237 | |
1238 /** | |
1239 * Draws the given string, using the receiver's current font and | |
1240 * foreground color. No tab expansion or carriage return processing | |
1241 * will be performed. The background of the rectangular area where | |
1242 * the string is being drawn will be filled with the receiver's | |
1243 * background color. | |
1244 * | |
1245 * @param string the string to be drawn | |
1246 * @param x the x coordinate of the top left corner of the rectangular area where the string is to be drawn | |
1247 * @param y the y coordinate of the top left corner of the rectangular area where the string is to be drawn | |
1248 * | |
1249 * @exception IllegalArgumentException <ul> | |
1250 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | |
1251 * </ul> | |
1252 * @exception DWTException <ul> | |
1253 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1254 * </ul> | |
1255 */ | |
1256 public void drawString (String string, int x, int y) { | |
1257 drawString(string, x, y, false); | |
1258 } | |
1259 | |
1260 /** | |
1261 * Draws the given string, using the receiver's current font and | |
1262 * foreground color. No tab expansion or carriage return processing | |
1263 * will be performed. If <code>isTransparent</code> is <code>true</code>, | |
1264 * then the background of the rectangular area where the string is being | |
1265 * drawn will not be modified, otherwise it will be filled with the | |
1266 * receiver's background color. | |
1267 * | |
1268 * @param string the string to be drawn | |
1269 * @param x the x coordinate of the top left corner of the rectangular area where the string is to be drawn | |
1270 * @param y the y coordinate of the top left corner of the rectangular area where the string is to be drawn | |
1271 * @param isTransparent if <code>true</code> the background will be transparent, otherwise it will be opaque | |
1272 * | |
1273 * @exception IllegalArgumentException <ul> | |
1274 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | |
1275 * </ul> | |
1276 * @exception DWTException <ul> | |
1277 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1278 * </ul> | |
1279 */ | |
1280 public void drawString(String string, int x, int y, bool isTransparent) { | |
1281 drawText(string, x, y, isTransparent ? DWT.DRAW_TRANSPARENT : 0); | |
1282 } | |
1283 | |
1284 /** | |
1285 * Draws the given string, using the receiver's current font and | |
1286 * foreground color. Tab expansion and carriage return processing | |
1287 * are performed. The background of the rectangular area where | |
1288 * the text is being drawn will be filled with the receiver's | |
1289 * background color. | |
1290 * | |
1291 * @param string the string to be drawn | |
1292 * @param x the x coordinate of the top left corner of the rectangular area where the text is to be drawn | |
1293 * @param y the y coordinate of the top left corner of the rectangular area where the text is to be drawn | |
1294 * | |
1295 * @exception IllegalArgumentException <ul> | |
1296 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | |
1297 * </ul> | |
1298 * @exception DWTException <ul> | |
1299 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1300 * </ul> | |
1301 */ | |
1302 public void drawText(String string, int x, int y) { | |
1303 drawText(string, x, y, DWT.DRAW_DELIMITER | DWT.DRAW_TAB); | |
1304 } | |
1305 | |
1306 /** | |
1307 * Draws the given string, using the receiver's current font and | |
1308 * foreground color. Tab expansion and carriage return processing | |
1309 * are performed. If <code>isTransparent</code> is <code>true</code>, | |
1310 * then the background of the rectangular area where the text is being | |
1311 * drawn will not be modified, otherwise it will be filled with the | |
1312 * receiver's background color. | |
1313 * | |
1314 * @param string the string to be drawn | |
1315 * @param x the x coordinate of the top left corner of the rectangular area where the text is to be drawn | |
1316 * @param y the y coordinate of the top left corner of the rectangular area where the text is to be drawn | |
1317 * @param isTransparent if <code>true</code> the background will be transparent, otherwise it will be opaque | |
1318 * | |
1319 * @exception IllegalArgumentException <ul> | |
1320 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | |
1321 * </ul> | |
1322 * @exception DWTException <ul> | |
1323 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1324 * </ul> | |
1325 */ | |
1326 public void drawText(String string, int x, int y, bool isTransparent) { | |
1327 int flags = DWT.DRAW_DELIMITER | DWT.DRAW_TAB; | |
1328 if (isTransparent) flags |= DWT.DRAW_TRANSPARENT; | |
1329 drawText(string, x, y, flags); | |
1330 } | |
1331 | |
1332 /** | |
1333 * Draws the given string, using the receiver's current font and | |
1334 * foreground color. Tab expansion, line delimiter and mnemonic | |
1335 * processing are performed according to the specified flags. If | |
1336 * <code>flags</code> includes <code>DRAW_TRANSPARENT</code>, | |
1337 * then the background of the rectangular area where the text is being | |
1338 * drawn will not be modified, otherwise it will be filled with the | |
1339 * receiver's background color. | |
1340 * <p> | |
1341 * The parameter <code>flags</code> may be a combination of: | |
1342 * <dl> | |
1343 * <dt><b>DRAW_DELIMITER</b></dt> | |
1344 * <dd>draw multiple lines</dd> | |
1345 * <dt><b>DRAW_TAB</b></dt> | |
1346 * <dd>expand tabs</dd> | |
1347 * <dt><b>DRAW_MNEMONIC</b></dt> | |
1348 * <dd>underline the mnemonic character</dd> | |
1349 * <dt><b>DRAW_TRANSPARENT</b></dt> | |
1350 * <dd>transparent background</dd> | |
1351 * </dl> | |
1352 * </p> | |
1353 * | |
1354 * @param string the string to be drawn | |
1355 * @param x the x coordinate of the top left corner of the rectangular area where the text is to be drawn | |
1356 * @param y the y coordinate of the top left corner of the rectangular area where the text is to be drawn | |
1357 * @param flags the flags specifying how to process the text | |
1358 * | |
1359 * @exception IllegalArgumentException <ul> | |
1360 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | |
1361 * </ul> | |
1362 * @exception DWTException <ul> | |
1363 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1364 * </ul> | |
1365 */ | |
1366 public void drawText (String string, int x, int y, int flags) { | |
1367 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1368 if (string is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | |
1369 NSGraphicsContext context = NSGraphicsContext.currentContext(); | |
1370 NSGraphicsContext.setCurrentContext(handle); | |
1371 checkGC(CLIPPING | TRANSFORM | FONT | FOREGROUND_FILL); | |
1372 NSAttributedString str = createString(string, flags); | |
1373 if (data.paintRect is null) { | |
1374 handle.saveGraphicsState(); | |
1375 NSAffineTransform transform = NSAffineTransform.transform(); | |
1376 transform.scaleXBy(1, -1); | |
1377 transform.translateXBy(0, -(str.size().height + 2 * y)); | |
1378 transform.concat(); | |
1379 } | |
1380 NSPoint pt = new NSPoint(); | |
1381 pt.x = x; | |
1382 pt.y = y; | |
1383 str.drawAtPoint(pt); | |
1384 str.release(); | |
1385 if (data.paintRect is null) { | |
1386 handle.restoreGraphicsState(); | |
1387 } | |
1388 NSGraphicsContext.setCurrentContext(context); | |
1389 } | |
1390 | |
1391 /** | |
1392 * Compares the argument to the receiver, and returns true | |
1393 * if they represent the <em>same</em> object using a class | |
1394 * specific comparison. | |
1395 * | |
1396 * @param object the object to compare with this object | |
1397 * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise | |
1398 * | |
1399 * @see #hashCode | |
1400 */ | |
1401 public bool equals(Object object) { | |
1402 if (object is this) return true; | |
1403 if (!(object instanceof GC)) return false; | |
1404 return handle is ((GC)object).handle; | |
1405 } | |
1406 | |
1407 /** | |
1408 * Fills the interior of a circular or elliptical arc within | |
1409 * the specified rectangular area, with the receiver's background | |
1410 * color. | |
1411 * <p> | |
1412 * The resulting arc begins at <code>startAngle</code> and extends | |
1413 * for <code>arcAngle</code> degrees, using the current color. | |
1414 * Angles are interpreted such that 0 degrees is at the 3 o'clock | |
1415 * position. A positive value indicates a counter-clockwise rotation | |
1416 * while a negative value indicates a clockwise rotation. | |
1417 * </p><p> | |
1418 * The center of the arc is the center of the rectangle whose origin | |
1419 * is (<code>x</code>, <code>y</code>) and whose size is specified by the | |
1420 * <code>width</code> and <code>height</code> arguments. | |
1421 * </p><p> | |
1422 * The resulting arc covers an area <code>width + 1</code> pixels wide | |
1423 * by <code>height + 1</code> pixels tall. | |
1424 * </p> | |
1425 * | |
1426 * @param x the x coordinate of the upper-left corner of the arc to be filled | |
1427 * @param y the y coordinate of the upper-left corner of the arc to be filled | |
1428 * @param width the width of the arc to be filled | |
1429 * @param height the height of the arc to be filled | |
1430 * @param startAngle the beginning angle | |
1431 * @param arcAngle the angular extent of the arc, relative to the start angle | |
1432 * | |
1433 * @exception DWTException <ul> | |
1434 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1435 * </ul> | |
1436 * | |
1437 * @see #drawArc | |
1438 */ | |
1439 public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) { | |
1440 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1441 NSGraphicsContext context = NSGraphicsContext.currentContext(); | |
1442 NSGraphicsContext.setCurrentContext(handle); | |
1443 checkGC(FILL); | |
1444 if (width < 0) { | |
1445 x = x + width; | |
1446 width = -width; | |
1447 } | |
1448 if (height < 0) { | |
1449 y = y + height; | |
1450 height = -height; | |
1451 } | |
1452 if (width is 0 || height is 0 || arcAngle is 0) return; | |
1453 handle.saveGraphicsState(); | |
1454 NSAffineTransform transform = NSAffineTransform.transform(); | |
1455 float xOffset = data.drawXOffset, yOffset = data.drawYOffset; | |
1456 transform.translateXBy(x + xOffset + width / 2f, y + yOffset + height / 2f); | |
1457 transform.scaleXBy(width / 2f, height / 2f); | |
1458 NSBezierPath path = data.path; | |
1459 NSPoint center = new NSPoint(); | |
1460 path.moveToPoint(center); | |
1461 float sAngle = -startAngle; | |
1462 float eAngle = -(startAngle + arcAngle); | |
1463 path.appendBezierPathWithArcWithCenter_radius_startAngle_endAngle_clockwise_(center, 1, sAngle, eAngle, arcAngle>0); | |
1464 path.closePath(); | |
1465 path.transformUsingAffineTransform(transform); | |
1466 path.fill(); | |
1467 path.removeAllPoints(); | |
1468 handle.restoreGraphicsState(); | |
1469 NSGraphicsContext.setCurrentContext(context); | |
1470 } | |
1471 | |
1472 /** | |
1473 * Fills the interior of the specified rectangle with a gradient | |
1474 * sweeping from left to right or top to bottom progressing | |
1475 * from the receiver's foreground color to its background color. | |
1476 * | |
1477 * @param x the x coordinate of the rectangle to be filled | |
1478 * @param y the y coordinate of the rectangle to be filled | |
1479 * @param width the width of the rectangle to be filled, may be negative | |
1480 * (inverts direction of gradient if horizontal) | |
1481 * @param height the height of the rectangle to be filled, may be negative | |
1482 * (inverts direction of gradient if vertical) | |
1483 * @param vertical if true sweeps from top to bottom, else | |
1484 * sweeps from left to right | |
1485 * | |
1486 * @exception DWTException <ul> | |
1487 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1488 * </ul> | |
1489 * | |
1490 * @see #drawRectangle(int, int, int, int) | |
1491 */ | |
1492 public void fillGradientRectangle(int x, int y, int width, int height, bool vertical) { | |
1493 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1494 NSGraphicsContext context = NSGraphicsContext.currentContext(); | |
1495 NSGraphicsContext.setCurrentContext(handle); | |
1496 checkGC(CLIPPING | TRANSFORM); | |
1497 if ((width is 0) || (height is 0)) return; | |
1498 | |
1499 RGB backgroundRGB, foregroundRGB; | |
1500 backgroundRGB = getBackground().getRGB(); | |
1501 foregroundRGB = getForeground().getRGB(); | |
1502 | |
1503 RGB fromRGB, toRGB; | |
1504 fromRGB = foregroundRGB; | |
1505 toRGB = backgroundRGB; | |
1506 bool swapColors = false; | |
1507 if (width < 0) { | |
1508 x += width; width = -width; | |
1509 if (! vertical) swapColors = true; | |
1510 } | |
1511 if (height < 0) { | |
1512 y += height; height = -height; | |
1513 if (vertical) swapColors = true; | |
1514 } | |
1515 if (swapColors) { | |
1516 fromRGB = backgroundRGB; | |
1517 toRGB = foregroundRGB; | |
1518 } | |
1519 if (fromRGB.equals(toRGB)) { | |
1520 fillRectangle(x, y, width, height); | |
1521 } else { | |
1522 NSColor startingColor = NSColor.colorWithDeviceRed(fromRGB.red / 255f, fromRGB.green / 255f, fromRGB.blue / 255f, data.alpha / 255f); | |
1523 NSColor endingColor = NSColor.colorWithDeviceRed(toRGB.red / 255f, toRGB.green / 255f, toRGB.blue / 255f, data.alpha / 255f); | |
1524 NSGradient gradient = ((NSGradient)new NSGradient().alloc()).initWithStartingColor(startingColor, endingColor); | |
1525 NSRect rect = new NSRect(); | |
1526 rect.x = x; | |
1527 rect.y = y; | |
1528 rect.width = width; | |
1529 rect.height = height; | |
1530 gradient.drawInRect_angle_(rect, vertical ? 90 : 0); | |
1531 gradient.release(); | |
1532 } | |
1533 NSGraphicsContext.setCurrentContext(context); | |
1534 } | |
1535 | |
1536 /** | |
1537 * Fills the interior of an oval, within the specified | |
1538 * rectangular area, with the receiver's background | |
1539 * color. | |
1540 * | |
1541 * @param x the x coordinate of the upper left corner of the oval to be filled | |
1542 * @param y the y coordinate of the upper left corner of the oval to be filled | |
1543 * @param width the width of the oval to be filled | |
1544 * @param height the height of the oval to be filled | |
1545 * | |
1546 * @exception DWTException <ul> | |
1547 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1548 * </ul> | |
1549 * | |
1550 * @see #drawOval | |
1551 */ | |
1552 public void fillOval(int x, int y, int width, int height) { | |
1553 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1554 NSGraphicsContext context = NSGraphicsContext.currentContext(); | |
1555 NSGraphicsContext.setCurrentContext(handle); | |
1556 checkGC(FILL); | |
1557 if (width < 0) { | |
1558 x = x + width; | |
1559 width = -width; | |
1560 } | |
1561 if (height < 0) { | |
1562 y = y + height; | |
1563 height = -height; | |
1564 } | |
1565 NSBezierPath path = data.path; | |
1566 NSRect rect = new NSRect(); | |
1567 rect.x = x; | |
1568 rect.y = y; | |
1569 rect.width = width; | |
1570 rect.height = height; | |
1571 path.appendBezierPathWithOvalInRect(rect); | |
1572 Pattern pattern = data.backgroundPattern; | |
1573 if (pattern !is null && pattern.gradient !is null) { | |
1574 fillPattern(path, pattern); | |
1575 } else { | |
1576 path.fill(); | |
1577 } | |
1578 path.removeAllPoints(); | |
1579 NSGraphicsContext.setCurrentContext(context); | |
1580 } | |
1581 | |
1582 void fillPattern(NSBezierPath path, Pattern pattern) { | |
1583 NSGraphicsContext context = NSGraphicsContext.currentContext(); | |
1584 NSGraphicsContext.setCurrentContext(handle); | |
1585 path.addClip(); | |
1586 pattern.gradient.drawFromPoint(pattern.pt1, pattern.pt2, OS.NSGradientDrawsAfterEndingLocation | OS.NSGradientDrawsBeforeStartingLocation); | |
1587 NSGraphicsContext.setCurrentContext(context); | |
1588 } | |
1589 | |
1590 /** | |
1591 * Fills the path described by the parameter. | |
1592 * <p> | |
1593 * This operation requires the operating system's advanced | |
1594 * graphics subsystem which may not be available on some | |
1595 * platforms. | |
1596 * </p> | |
1597 * | |
1598 * @param path the path to fill | |
1599 * | |
1600 * @exception IllegalArgumentException <ul> | |
1601 * <li>ERROR_NULL_ARGUMENT - if the parameter is null</li> | |
1602 * <li>ERROR_INVALID_ARGUMENT - if the parameter has been disposed</li> | |
1603 * </ul> | |
1604 * @exception DWTException <ul> | |
1605 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1606 * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> | |
1607 * </ul> | |
1608 * | |
1609 * @see Path | |
1610 * | |
1611 * @since 3.1 | |
1612 */ | |
1613 public void fillPath(Path path) { | |
1614 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1615 if (path is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | |
1616 if (path.handle is null) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
1617 NSGraphicsContext context = NSGraphicsContext.currentContext(); | |
1618 NSGraphicsContext.setCurrentContext(handle); | |
1619 checkGC(FILL); | |
1620 NSBezierPath drawPath = data.path; | |
1621 drawPath.appendBezierPath(path.handle); | |
1622 Pattern pattern = data.backgroundPattern; | |
1623 if (pattern !is null && pattern.gradient !is null) { | |
1624 fillPattern(drawPath, pattern); | |
1625 } else { | |
1626 drawPath.fill(); | |
1627 } | |
1628 drawPath.removeAllPoints(); | |
1629 NSGraphicsContext.setCurrentContext(context); | |
1630 } | |
1631 | |
1632 /** | |
1633 * Fills the interior of the closed polygon which is defined by the | |
1634 * specified array of integer coordinates, using the receiver's | |
1635 * background color. The array contains alternating x and y values | |
1636 * which are considered to represent points which are the vertices of | |
1637 * the polygon. Lines are drawn between each consecutive pair, and | |
1638 * between the first pair and last pair in the array. | |
1639 * | |
1640 * @param pointArray an array of alternating x and y values which are the vertices of the polygon | |
1641 * | |
1642 * @exception IllegalArgumentException <ul> | |
1643 * <li>ERROR_NULL_ARGUMENT if pointArray is null</li> | |
1644 * </ul> | |
1645 * @exception DWTException <ul> | |
1646 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1647 * </ul> | |
1648 * | |
1649 * @see #drawPolygon | |
1650 */ | |
1651 public void fillPolygon(int[] pointArray) { | |
1652 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1653 if (pointArray is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | |
1654 NSGraphicsContext context = NSGraphicsContext.currentContext(); | |
1655 NSGraphicsContext.setCurrentContext(handle); | |
1656 checkGC(FILL); | |
1657 if (pointArray.length < 4) return; | |
1658 NSBezierPath path = data.path; | |
1659 NSPoint pt = new NSPoint(); | |
1660 pt.x = pointArray[0]; | |
1661 pt.y = pointArray[1]; | |
1662 path.moveToPoint(pt); | |
1663 int end = pointArray.length / 2 * 2; | |
1664 for (int i = 2; i < end; i+=2) { | |
1665 pt.x = pointArray[i]; | |
1666 pt.y = pointArray[i+1]; | |
1667 path.lineToPoint(pt); | |
1668 } | |
1669 path.closePath(); | |
1670 Pattern pattern = data.backgroundPattern; | |
1671 if (pattern !is null && pattern.gradient !is null) { | |
1672 fillPattern(path, pattern); | |
1673 } else { | |
1674 path.fill(); | |
1675 } | |
1676 path.removeAllPoints(); | |
1677 NSGraphicsContext.setCurrentContext(context); | |
1678 } | |
1679 | |
1680 /** | |
1681 * Fills the interior of the rectangle specified by the arguments, | |
1682 * using the receiver's background color. | |
1683 * | |
1684 * @param x the x coordinate of the rectangle to be filled | |
1685 * @param y the y coordinate of the rectangle to be filled | |
1686 * @param width the width of the rectangle to be filled | |
1687 * @param height the height of the rectangle to be filled | |
1688 * | |
1689 * @exception DWTException <ul> | |
1690 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1691 * </ul> | |
1692 * | |
1693 * @see #drawRectangle(int, int, int, int) | |
1694 */ | |
1695 public void fillRectangle(int x, int y, int width, int height) { | |
1696 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1697 NSGraphicsContext context = NSGraphicsContext.currentContext(); | |
1698 NSGraphicsContext.setCurrentContext(handle); | |
1699 checkGC(FILL); | |
1700 if (width < 0) { | |
1701 x = x + width; | |
1702 width = -width; | |
1703 } | |
1704 if (height < 0) { | |
1705 y = y + height; | |
1706 height = -height; | |
1707 } | |
1708 NSRect rect = new NSRect(); | |
1709 rect.x = x; | |
1710 rect.y = y; | |
1711 rect.width = width; | |
1712 rect.height = height; | |
1713 NSBezierPath path = data.path; | |
1714 path.appendBezierPathWithRect(rect); | |
1715 Pattern pattern = data.backgroundPattern; | |
1716 if (pattern !is null && pattern.gradient !is null) { | |
1717 fillPattern(path, pattern); | |
1718 } else { | |
1719 path.fill(); | |
1720 } | |
1721 path.removeAllPoints(); | |
1722 NSGraphicsContext.setCurrentContext(context); | |
1723 } | |
1724 | |
1725 /** | |
1726 * Fills the interior of the specified rectangle, using the receiver's | |
1727 * background color. | |
1728 * | |
1729 * @param rect the rectangle to be filled | |
1730 * | |
1731 * @exception IllegalArgumentException <ul> | |
1732 * <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li> | |
1733 * </ul> | |
1734 * @exception DWTException <ul> | |
1735 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1736 * </ul> | |
1737 * | |
1738 * @see #drawRectangle(int, int, int, int) | |
1739 */ | |
1740 public void fillRectangle(Rectangle rect) { | |
1741 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1742 if (rect is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | |
1743 fillRectangle(rect.x, rect.y, rect.width, rect.height); | |
1744 } | |
1745 | |
1746 /** | |
1747 * Fills the interior of the round-cornered rectangle specified by | |
1748 * the arguments, using the receiver's background color. | |
1749 * | |
1750 * @param x the x coordinate of the rectangle to be filled | |
1751 * @param y the y coordinate of the rectangle to be filled | |
1752 * @param width the width of the rectangle to be filled | |
1753 * @param height the height of the rectangle to be filled | |
1754 * @param arcWidth the width of the arc | |
1755 * @param arcHeight the height of the arc | |
1756 * | |
1757 * @exception DWTException <ul> | |
1758 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1759 * </ul> | |
1760 * | |
1761 * @see #drawRoundRectangle | |
1762 */ | |
1763 public void fillRoundRectangle(int x, int y, int width, int height, int arcWidth, int arcHeight) { | |
1764 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1765 NSGraphicsContext context = NSGraphicsContext.currentContext(); | |
1766 NSGraphicsContext.setCurrentContext(handle); | |
1767 checkGC(FILL); | |
1768 if (arcWidth is 0 || arcHeight is 0) { | |
1769 fillRectangle(x, y, width, height); | |
1770 return; | |
1771 } | |
1772 NSBezierPath path = data.path; | |
1773 NSRect rect = new NSRect(); | |
1774 rect.x = x; | |
1775 rect.y = y; | |
1776 rect.width = width; | |
1777 rect.height = height; | |
1778 path.appendBezierPathWithRoundedRect(rect, arcWidth, arcHeight); | |
1779 Pattern pattern = data.backgroundPattern; | |
1780 if (pattern !is null && pattern.gradient !is null) { | |
1781 fillPattern(path, pattern); | |
1782 } else { | |
1783 path.fill(); | |
1784 } | |
1785 path.removeAllPoints(); | |
1786 NSGraphicsContext.setCurrentContext(context); | |
1787 } | |
1788 | |
1789 void flush () { | |
1790 } | |
1791 | |
1792 /** | |
1793 * Returns the <em>advance width</em> of the specified character in | |
1794 * the font which is currently selected into the receiver. | |
1795 * <p> | |
1796 * The advance width is defined as the horizontal distance the cursor | |
1797 * should move after printing the character in the selected font. | |
1798 * </p> | |
1799 * | |
1800 * @param ch the character to measure | |
1801 * @return the distance in the x direction to move past the character before painting the next | |
1802 * | |
1803 * @exception DWTException <ul> | |
1804 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1805 * </ul> | |
1806 */ | |
1807 public int getAdvanceWidth(char ch) { | |
1808 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1809 //NOT DONE | |
1810 return stringExtent(new String(new char[]{ch})).x; | |
1811 } | |
1812 | |
1813 /** | |
1814 * Returns the background color. | |
1815 * | |
1816 * @return the receiver's background color | |
1817 * | |
1818 * @exception DWTException <ul> | |
1819 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1820 * </ul> | |
1821 */ | |
1822 public Color getBackground() { | |
1823 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1824 return Color.cocoa_new (data.device, data.background); | |
1825 } | |
1826 | |
1827 /** | |
1828 * Returns the background pattern. The default value is | |
1829 * <code>null</code>. | |
1830 * | |
1831 * @return the receiver's background pattern | |
1832 * | |
1833 * @exception DWTException <ul> | |
1834 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1835 * </ul> | |
1836 * | |
1837 * @see Pattern | |
1838 * | |
1839 * @since 3.1 | |
1840 */ | |
1841 public Pattern getBackgroundPattern() { | |
1842 if (handle is null) DWT.error(DWT.ERROR_WIDGET_DISPOSED); | |
1843 return data.backgroundPattern; | |
1844 } | |
1845 | |
1846 /** | |
1847 * Returns <code>true</code> if receiver is using the operating system's | |
1848 * advanced graphics subsystem. Otherwise, <code>false</code> is returned | |
1849 * to indicate that normal graphics are in use. | |
1850 * <p> | |
1851 * Advanced graphics may not be installed for the operating system. In this | |
1852 * case, <code>false</code> is always returned. Some operating system have | |
1853 * only one graphics subsystem. If this subsystem supports advanced graphics, | |
1854 * then <code>true</code> is always returned. If any graphics operation such | |
1855 * as alpha, antialias, patterns, interpolation, paths, clipping or transformation | |
1856 * has caused the receiver to switch from regular to advanced graphics mode, | |
1857 * <code>true</code> is returned. If the receiver has been explicitly switched | |
1858 * to advanced mode and this mode is supported, <code>true</code> is returned. | |
1859 * </p> | |
1860 * | |
1861 * @return the advanced value | |
1862 * | |
1863 * @exception DWTException <ul> | |
1864 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1865 * </ul> | |
1866 * | |
1867 * @see #setAdvanced | |
1868 * | |
1869 * @since 3.1 | |
1870 */ | |
1871 public bool getAdvanced() { | |
1872 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1873 return true; | |
1874 } | |
1875 | |
1876 /** | |
1877 * Returns the receiver's alpha value. | |
1878 * | |
1879 * @return the alpha value | |
1880 * | |
1881 * @exception DWTException <ul> | |
1882 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1883 * </ul> | |
1884 * | |
1885 * @since 3.1 | |
1886 */ | |
1887 public int getAlpha() { | |
1888 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1889 return data.alpha; | |
1890 } | |
1891 | |
1892 /** | |
1893 * Returns the receiver's anti-aliasing setting value, which will be | |
1894 * one of <code>DWT.DEFAULT</code>, <code>DWT.OFF</code> or | |
1895 * <code>DWT.ON</code>. Note that this controls anti-aliasing for all | |
1896 * <em>non-text drawing</em> operations. | |
1897 * | |
1898 * @return the anti-aliasing setting | |
1899 * | |
1900 * @exception DWTException <ul> | |
1901 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1902 * </ul> | |
1903 * | |
1904 * @see #getTextAntialias | |
1905 * | |
1906 * @since 3.1 | |
1907 */ | |
1908 public int getAntialias() { | |
1909 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1910 return data.antialias; | |
1911 } | |
1912 | |
1913 /** | |
1914 * Returns the width of the specified character in the font | |
1915 * selected into the receiver. | |
1916 * <p> | |
1917 * The width is defined as the space taken up by the actual | |
1918 * character, not including the leading and tailing whitespace | |
1919 * or overhang. | |
1920 * </p> | |
1921 * | |
1922 * @param ch the character to measure | |
1923 * @return the width of the character | |
1924 * | |
1925 * @exception DWTException <ul> | |
1926 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1927 * </ul> | |
1928 */ | |
1929 public int getCharWidth(char ch) { | |
1930 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1931 //NOT DONE | |
1932 return stringExtent(new String(new char[]{ch})).x; | |
1933 } | |
1934 | |
1935 /** | |
1936 * Returns the bounding rectangle of the receiver's clipping | |
1937 * region. If no clipping region is set, the return value | |
1938 * will be a rectangle which covers the entire bounds of the | |
1939 * object the receiver is drawing on. | |
1940 * | |
1941 * @return the bounding rectangle of the clipping region | |
1942 * | |
1943 * @exception DWTException <ul> | |
1944 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
1945 * </ul> | |
1946 */ | |
1947 public Rectangle getClipping() { | |
1948 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
1949 NSRect rect = null; | |
1950 if (data.view !is null) { | |
1951 rect = data.view.bounds(); | |
1952 } else { | |
1953 rect = new NSRect(); | |
1954 if (data.image !is null) { | |
1955 NSSize size = data.image.handle.size(); | |
1956 rect.width = size.width; | |
1957 rect.height = size.height; | |
1958 } else if (data.size !is null) { | |
1959 rect.width = data.size.width; | |
1960 rect.height = data.size.height; | |
1961 } | |
1962 } | |
1963 if (data.paintRect !is null || data.clipPath !is null || data.inverseTransform !is null) { | |
1964 if (data.paintRect !is null) { | |
1965 OS.NSIntersectionRect(rect, rect, data.paintRect); | |
1966 } | |
1967 if (data.clipPath !is null) { | |
1968 NSRect clip = data.clipPath.bounds(); | |
1969 OS.NSIntersectionRect(rect, rect, clip); | |
1970 } | |
1971 if (data.inverseTransform !is null && rect.width > 0 && rect.height > 0) { | |
1972 NSPoint pt = new NSPoint(); | |
1973 pt.x = rect.x; | |
1974 pt.y = rect.y; | |
1975 NSSize size = new NSSize(); | |
1976 size.width = rect.width; | |
1977 size.height = rect.height; | |
1978 pt = data.inverseTransform.transformPoint(pt); | |
1979 size = data.inverseTransform.transformSize(size); | |
1980 rect.x = pt.x; | |
1981 rect.y = pt.y; | |
1982 rect.width = size.width; | |
1983 rect.height = size.height; | |
1984 } | |
1985 } | |
1986 return new Rectangle((int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height); | |
1987 } | |
1988 | |
1989 /** | |
1990 * Sets the region managed by the argument to the current | |
1991 * clipping region of the receiver. | |
1992 * | |
1993 * @param region the region to fill with the clipping region | |
1994 * | |
1995 * @exception IllegalArgumentException <ul> | |
1996 * <li>ERROR_NULL_ARGUMENT - if the region is null</li> | |
1997 * <li>ERROR_INVALID_ARGUMENT - if the region is disposed</li> | |
1998 * </ul> | |
1999 * @exception DWTException <ul> | |
2000 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2001 * </ul> | |
2002 */ | |
2003 public void getClipping(Region region) { | |
2004 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2005 if (region is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | |
2006 if (region.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
2007 region.subtract(region); | |
2008 NSRect rect = null; | |
2009 if (data.view !is null) { | |
2010 rect = data.view.bounds(); | |
2011 } else { | |
2012 rect = new NSRect(); | |
2013 if (data.image !is null) { | |
2014 NSSize size = data.image.handle.size(); | |
2015 rect.width = size.width; | |
2016 rect.height = size.height; | |
2017 } else if (data.size !is null) { | |
2018 rect.width = data.size.width; | |
2019 rect.height = data.size.height; | |
2020 } | |
2021 } | |
2022 region.add((int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height); | |
2023 NSRect paintRect = data.paintRect; | |
2024 if (paintRect !is null) { | |
2025 region.intersect((int)paintRect.x, (int)paintRect.y, (int)paintRect.width, (int)paintRect.height); | |
2026 } | |
2027 if (data.clipPath !is null) { | |
2028 NSBezierPath clip = data.clipPath.bezierPathByFlatteningPath(); | |
2029 int count = clip.elementCount(); | |
2030 int pointCount = 0; | |
2031 Region clipRgn = new Region(device); | |
2032 int[] pointArray = new int[count * 2]; | |
2033 int points = OS.malloc(NSPoint.sizeof); | |
2034 if (points is 0) DWT.error(DWT.ERROR_NO_HANDLES); | |
2035 NSPoint pt = new NSPoint(); | |
2036 for (int i = 0; i < count; i++) { | |
2037 int element = clip.elementAtIndex_associatedPoints_(i, points); | |
2038 switch (element) { | |
2039 case OS.NSMoveToBezierPathElement: | |
2040 if (pointCount !is 0) clipRgn.add(pointArray, pointCount); | |
2041 pointCount = 0; | |
2042 OS.memmove(pt, points, NSPoint.sizeof); | |
2043 pointArray[pointCount++] = (int)pt.x; | |
2044 pointArray[pointCount++] = (int)pt.y; | |
2045 break; | |
2046 case OS.NSLineToBezierPathElement: | |
2047 OS.memmove(pt, points, NSPoint.sizeof); | |
2048 pointArray[pointCount++] = (int)pt.x; | |
2049 pointArray[pointCount++] = (int)pt.y; | |
2050 break; | |
2051 case OS.NSClosePathBezierPathElement: | |
2052 if (pointCount !is 0) clipRgn.add(pointArray, pointCount); | |
2053 pointCount = 0; | |
2054 break; | |
2055 } | |
2056 } | |
2057 if (pointCount !is 0) clipRgn.add(pointArray, pointCount); | |
2058 OS.free(points); | |
2059 region.intersect(clipRgn); | |
2060 clipRgn.dispose(); | |
2061 } | |
2062 if (data.inverseTransform !is null) { | |
2063 region.convertRgn(data.inverseTransform); | |
2064 } | |
2065 } | |
2066 | |
2067 /** | |
2068 * Returns the receiver's fill rule, which will be one of | |
2069 * <code>DWT.FILL_EVEN_ODD</code> or <code>DWT.FILL_WINDING</code>. | |
2070 * | |
2071 * @return the receiver's fill rule | |
2072 * | |
2073 * @exception DWTException <ul> | |
2074 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2075 * </ul> | |
2076 * | |
2077 * @since 3.1 | |
2078 */ | |
2079 public int getFillRule() { | |
2080 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2081 return data.fillRule; | |
2082 } | |
2083 | |
2084 /** | |
2085 * Returns the font currently being used by the receiver | |
2086 * to draw and measure text. | |
2087 * | |
2088 * @return the receiver's font | |
2089 * | |
2090 * @exception DWTException <ul> | |
2091 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2092 * </ul> | |
2093 */ | |
2094 public Font getFont() { | |
2095 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2096 return data.font; | |
2097 } | |
2098 | |
2099 /** | |
2100 * Returns a FontMetrics which contains information | |
2101 * about the font currently being used by the receiver | |
2102 * to draw and measure text. | |
2103 * | |
2104 * @return font metrics for the receiver's font | |
2105 * | |
2106 * @exception DWTException <ul> | |
2107 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2108 * </ul> | |
2109 */ | |
2110 public FontMetrics getFontMetrics() { | |
2111 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2112 checkGC(FONT); | |
2113 NSFont font = data.font.handle; | |
2114 int ascent = (int)(0.5f + font.ascender()); | |
2115 int descent = (int)(0.5f + (-font.descender() + font.leading())); | |
2116 String s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; | |
2117 int averageCharWidth = stringExtent(s).x / s.length(); | |
2118 return FontMetrics.cocoa_new(ascent, descent, averageCharWidth, 0, ascent + descent); | |
2119 } | |
2120 | |
2121 /** | |
2122 * Returns the receiver's foreground color. | |
2123 * | |
2124 * @return the color used for drawing foreground things | |
2125 * | |
2126 * @exception DWTException <ul> | |
2127 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2128 * </ul> | |
2129 */ | |
2130 public Color getForeground() { | |
2131 if (handle is null) DWT.error(DWT.ERROR_WIDGET_DISPOSED); | |
2132 return Color.cocoa_new(data.device, data.foreground); | |
2133 } | |
2134 | |
2135 /** | |
2136 * Returns the foreground pattern. The default value is | |
2137 * <code>null</code>. | |
2138 * | |
2139 * @return the receiver's foreground pattern | |
2140 * | |
2141 * @exception DWTException <ul> | |
2142 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2143 * </ul> | |
2144 * | |
2145 * @see Pattern | |
2146 * | |
2147 * @since 3.1 | |
2148 */ | |
2149 public Pattern getForegroundPattern() { | |
2150 if (handle is null) DWT.error(DWT.ERROR_WIDGET_DISPOSED); | |
2151 return data.foregroundPattern; | |
2152 } | |
2153 | |
2154 /** | |
2155 * Returns the GCData. | |
2156 * <p> | |
2157 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public | |
2158 * API for <code>GC</code>. It is marked public only so that it | |
2159 * can be shared within the packages provided by DWT. It is not | |
2160 * available on all platforms, and should never be called from | |
2161 * application code. | |
2162 * </p> | |
2163 * | |
2164 * @return the receiver's GCData | |
2165 * | |
2166 * @exception DWTException <ul> | |
2167 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2168 * </ul> | |
2169 * | |
2170 * @see GCData | |
2171 * | |
2172 * @since 3.2 | |
2173 */ | |
2174 public GCData getGCData() { | |
2175 if (handle is null) DWT.error(DWT.ERROR_WIDGET_DISPOSED); | |
2176 return data; | |
2177 } | |
2178 | |
2179 /** | |
2180 * Returns the receiver's interpolation setting, which will be one of | |
2181 * <code>DWT.DEFAULT</code>, <code>DWT.NONE</code>, | |
2182 * <code>DWT.LOW</code> or <code>DWT.HIGH</code>. | |
2183 * | |
2184 * @return the receiver's interpolation setting | |
2185 * | |
2186 * @exception DWTException <ul> | |
2187 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2188 * </ul> | |
2189 * | |
2190 * @since 3.1 | |
2191 */ | |
2192 public int getInterpolation() { | |
2193 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2194 int interpolation = handle.imageInterpolation(); | |
2195 switch (interpolation) { | |
2196 case OS.NSImageInterpolationDefault: return DWT.DEFAULT; | |
2197 case OS.NSImageInterpolationNone: return DWT.NONE; | |
2198 case OS.NSImageInterpolationLow: return DWT.LOW; | |
2199 case OS.NSImageInterpolationHigh: return DWT.HIGH; | |
2200 } | |
2201 return DWT.DEFAULT; | |
2202 } | |
2203 | |
2204 /** | |
2205 * Returns the receiver's line attributes. | |
2206 * | |
2207 * @return the line attributes used for drawing lines | |
2208 * | |
2209 * @exception DWTException <ul> | |
2210 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2211 * </ul> | |
2212 * | |
2213 * @since 3.3 | |
2214 */ | |
2215 public LineAttributes getLineAttributes() { | |
2216 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2217 float[] dashes = null; | |
2218 if (data.lineDashes !is null) { | |
2219 dashes = new float[data.lineDashes.length]; | |
2220 System.arraycopy(data.lineDashes, 0, dashes, 0, dashes.length); | |
2221 } | |
2222 return new LineAttributes(data.lineWidth, data.lineCap, data.lineJoin, data.lineStyle, dashes, data.lineDashesOffset, data.lineMiterLimit); | |
2223 } | |
2224 | |
2225 /** | |
2226 * Returns the receiver's line cap style, which will be one | |
2227 * of the constants <code>DWT.CAP_FLAT</code>, <code>DWT.CAP_ROUND</code>, | |
2228 * or <code>DWT.CAP_SQUARE</code>. | |
2229 * | |
2230 * @return the cap style used for drawing lines | |
2231 * | |
2232 * @exception DWTException <ul> | |
2233 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2234 * </ul> | |
2235 * | |
2236 * @since 3.1 | |
2237 */ | |
2238 public int getLineCap() { | |
2239 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2240 return data.lineCap; | |
2241 } | |
2242 | |
2243 /** | |
2244 * Returns the receiver's line dash style. The default value is | |
2245 * <code>null</code>. | |
2246 * | |
2247 * @return the line dash style used for drawing lines | |
2248 * | |
2249 * @exception DWTException <ul> | |
2250 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2251 * </ul> | |
2252 * | |
2253 * @since 3.1 | |
2254 */ | |
2255 public int[] getLineDash() { | |
2256 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2257 if (data.lineDashes is null) return null; | |
2258 int[] lineDashes = new int[data.lineDashes.length]; | |
2259 for (int i = 0; i < lineDashes.length; i++) { | |
2260 lineDashes[i] = (int)data.lineDashes[i]; | |
2261 } | |
2262 return lineDashes; | |
2263 } | |
2264 | |
2265 /** | |
2266 * Returns the receiver's line join style, which will be one | |
2267 * of the constants <code>DWT.JOIN_MITER</code>, <code>DWT.JOIN_ROUND</code>, | |
2268 * or <code>DWT.JOIN_BEVEL</code>. | |
2269 * | |
2270 * @return the join style used for drawing lines | |
2271 * | |
2272 * @exception DWTException <ul> | |
2273 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2274 * </ul> | |
2275 * | |
2276 * @since 3.1 | |
2277 */ | |
2278 public int getLineJoin() { | |
2279 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2280 return data.lineJoin; | |
2281 } | |
2282 | |
2283 /** | |
2284 * Returns the receiver's line style, which will be one | |
2285 * of the constants <code>DWT.LINE_SOLID</code>, <code>DWT.LINE_DASH</code>, | |
2286 * <code>DWT.LINE_DOT</code>, <code>DWT.LINE_DASHDOT</code> or | |
2287 * <code>DWT.LINE_DASHDOTDOT</code>. | |
2288 * | |
2289 * @return the style used for drawing lines | |
2290 * | |
2291 * @exception DWTException <ul> | |
2292 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2293 * </ul> | |
2294 */ | |
2295 public int getLineStyle() { | |
2296 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2297 return data.lineStyle; | |
2298 } | |
2299 | |
2300 /** | |
2301 * Returns the width that will be used when drawing lines | |
2302 * for all of the figure drawing operations (that is, | |
2303 * <code>drawLine</code>, <code>drawRectangle</code>, | |
2304 * <code>drawPolyline</code>, and so forth. | |
2305 * | |
2306 * @return the receiver's line width | |
2307 * | |
2308 * @exception DWTException <ul> | |
2309 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2310 * </ul> | |
2311 */ | |
2312 public int getLineWidth() { | |
2313 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2314 return (int)data.lineWidth; | |
2315 } | |
2316 | |
2317 /** | |
2318 * Returns the receiver's style information. | |
2319 * <p> | |
2320 * Note that the value which is returned by this method <em>may | |
2321 * not match</em> the value which was provided to the constructor | |
2322 * when the receiver was created. This can occur when the underlying | |
2323 * operating system does not support a particular combination of | |
2324 * requested styles. | |
2325 * </p> | |
2326 * | |
2327 * @return the style bits | |
2328 * | |
2329 * @exception DWTException <ul> | |
2330 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2331 * </ul> | |
2332 * | |
2333 * @since 2.1.2 | |
2334 */ | |
2335 public int getStyle () { | |
2336 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2337 return data.style; | |
2338 } | |
2339 | |
2340 /** | |
2341 * Returns the receiver's text drawing anti-aliasing setting value, | |
2342 * which will be one of <code>DWT.DEFAULT</code>, <code>DWT.OFF</code> or | |
2343 * <code>DWT.ON</code>. Note that this controls anti-aliasing | |
2344 * <em>only</em> for text drawing operations. | |
2345 * | |
2346 * @return the anti-aliasing setting | |
2347 * | |
2348 * @exception DWTException <ul> | |
2349 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2350 * </ul> | |
2351 * | |
2352 * @see #getAntialias | |
2353 * | |
2354 * @since 3.1 | |
2355 */ | |
2356 public int getTextAntialias() { | |
2357 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2358 return data.textAntialias; | |
2359 } | |
2360 | |
2361 /** | |
2362 * Sets the parameter to the transform that is currently being | |
2363 * used by the receiver. | |
2364 * | |
2365 * @param transform the destination to copy the transform into | |
2366 * | |
2367 * @exception IllegalArgumentException <ul> | |
2368 * <li>ERROR_NULL_ARGUMENT - if the parameter is null</li> | |
2369 * <li>ERROR_INVALID_ARGUMENT - if the parameter has been disposed</li> | |
2370 * </ul> | |
2371 * @exception DWTException <ul> | |
2372 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2373 * </ul> | |
2374 * | |
2375 * @see Transform | |
2376 * | |
2377 * @since 3.1 | |
2378 */ | |
2379 public void getTransform (Transform transform) { | |
2380 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2381 if (transform is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | |
2382 if (transform.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
2383 NSAffineTransform cmt = data.transform; | |
2384 if (cmt !is null) { | |
2385 NSAffineTransformStruct struct = cmt.transformStruct(); | |
2386 transform.handle.setTransformStruct(struct); | |
2387 } else { | |
2388 transform.setElements(1, 0, 0, 1, 0, 0); | |
2389 } | |
2390 } | |
2391 | |
2392 /** | |
2393 * Returns <code>true</code> if this GC is drawing in the mode | |
2394 * where the resulting color in the destination is the | |
2395 * <em>exclusive or</em> of the color values in the source | |
2396 * and the destination, and <code>false</code> if it is | |
2397 * drawing in the mode where the destination color is being | |
2398 * replaced with the source color value. | |
2399 * | |
2400 * @return <code>true</code> true if the receiver is in XOR mode, and false otherwise | |
2401 * | |
2402 * @exception DWTException <ul> | |
2403 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2404 * </ul> | |
2405 */ | |
2406 public bool getXORMode() { | |
2407 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2408 return data.xorMode; | |
2409 } | |
2410 | |
2411 /** | |
2412 * Returns an integer hash code for the receiver. Any two | |
2413 * objects that return <code>true</code> when passed to | |
2414 * <code>equals</code> must return the same value for this | |
2415 * method. | |
2416 * | |
2417 * @return the receiver's hash | |
2418 * | |
2419 * @exception DWTException <ul> | |
2420 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2421 * </ul> | |
2422 * | |
2423 * @see #equals | |
2424 */ | |
2425 public int hashCode() { | |
2426 return handle !is null ? handle.id : 0; | |
2427 } | |
2428 | |
2429 void init(Drawable drawable, GCData data, int context) { | |
2430 if (data.foreground !is null) data.state &= ~(FOREGROUND | FOREGROUND_FILL); | |
2431 if (data.background !is null) data.state &= ~BACKGROUND; | |
2432 if (data.font !is null) data.state &= ~FONT; | |
2433 data.state &= ~DRAW_OFFSET; | |
2434 | |
2435 Image image = data.image; | |
2436 if (image !is null) image.memGC = this; | |
2437 this.drawable = drawable; | |
2438 this.data = data; | |
2439 handle = new NSGraphicsContext(context); | |
2440 handle.retain(); | |
2441 handle.saveGraphicsState(); | |
2442 data.path = NSBezierPath.bezierPath(); | |
2443 data.path.setWindingRule(data.fillRule is DWT.FILL_WINDING ? OS.NSNonZeroWindingRule : OS.NSEvenOddWindingRule); | |
2444 data.path.retain(); | |
2445 } | |
2446 | |
2447 /** | |
2448 * Returns <code>true</code> if the receiver has a clipping | |
2449 * region set into it, and <code>false</code> otherwise. | |
2450 * If this method returns false, the receiver will draw on all | |
2451 * available space in the destination. If it returns true, | |
2452 * it will draw only in the area that is covered by the region | |
2453 * that can be accessed with <code>getClipping(region)</code>. | |
2454 * | |
2455 * @return <code>true</code> if the GC has a clipping region, and <code>false</code> otherwise | |
2456 * | |
2457 * @exception DWTException <ul> | |
2458 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2459 * </ul> | |
2460 */ | |
2461 public bool isClipped() { | |
2462 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2463 return data.clipPath !is null; | |
2464 } | |
2465 | |
2466 /** | |
2467 * Returns <code>true</code> if the GC has been disposed, | |
2468 * and <code>false</code> otherwise. | |
2469 * <p> | |
2470 * This method gets the dispose state for the GC. | |
2471 * When a GC has been disposed, it is an error to | |
2472 * invoke any other method using the GC. | |
2473 * | |
2474 * @return <code>true</code> when the GC is disposed and <code>false</code> otherwise | |
2475 */ | |
2476 public bool isDisposed() { | |
2477 return handle is null; | |
2478 } | |
2479 | |
2480 bool isIdentity(float[] transform) { | |
2481 return transform[0] is 1 && transform[1] is 0 && transform[2] is 0 | |
2482 && transform[3] is 1 && transform[4] is 0 && transform[5] is 0; | |
2483 } | |
2484 | |
2485 /** | |
2486 * Sets the receiver to always use the operating system's advanced graphics | |
2487 * subsystem for all graphics operations if the argument is <code>true</code>. | |
2488 * If the argument is <code>false</code>, the advanced graphics subsystem is | |
2489 * no longer used, advanced graphics state is cleared and the normal graphics | |
2490 * subsystem is used from now on. | |
2491 * <p> | |
2492 * Normally, the advanced graphics subsystem is invoked automatically when | |
2493 * any one of the alpha, antialias, patterns, interpolation, paths, clipping | |
2494 * or transformation operations in the receiver is requested. When the receiver | |
2495 * is switched into advanced mode, the advanced graphics subsystem performs both | |
2496 * advanced and normal graphics operations. Because the two subsystems are | |
2497 * different, their output may differ. Switching to advanced graphics before | |
2498 * any graphics operations are performed ensures that the output is consistent. | |
2499 * </p><p> | |
2500 * Advanced graphics may not be installed for the operating system. In this | |
2501 * case, this operation does nothing. Some operating system have only one | |
2502 * graphics subsystem, so switching from normal to advanced graphics does | |
2503 * nothing. However, switching from advanced to normal graphics will always | |
2504 * clear the advanced graphics state, even for operating systems that have | |
2505 * only one graphics subsystem. | |
2506 * </p> | |
2507 * | |
2508 * @param advanced the new advanced graphics state | |
2509 * | |
2510 * @exception DWTException <ul> | |
2511 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2512 * </ul> | |
2513 * | |
2514 * @see #setAlpha | |
2515 * @see #setAntialias | |
2516 * @see #setBackgroundPattern | |
2517 * @see #setClipping(Path) | |
2518 * @see #setForegroundPattern | |
2519 * @see #setLineAttributes | |
2520 * @see #setInterpolation | |
2521 * @see #setTextAntialias | |
2522 * @see #setTransform | |
2523 * @see #getAdvanced | |
2524 * | |
2525 * @since 3.1 | |
2526 */ | |
2527 public void setAdvanced(bool advanced) { | |
2528 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2529 if (!advanced) { | |
2530 setAlpha(0xFF); | |
2531 setAntialias(DWT.DEFAULT); | |
2532 setBackgroundPattern(null); | |
2533 setClipping((Rectangle)null); | |
2534 setForegroundPattern(null); | |
2535 setInterpolation(DWT.DEFAULT); | |
2536 setTextAntialias(DWT.DEFAULT); | |
2537 setTransform(null); | |
2538 } | |
2539 } | |
2540 | |
2541 /** | |
2542 * Sets the receiver's alpha value. | |
2543 * <p> | |
2544 * This operation requires the operating system's advanced | |
2545 * graphics subsystem which may not be available on some | |
2546 * platforms. | |
2547 * </p> | |
2548 * @param alpha the alpha value | |
2549 * | |
2550 * @exception DWTException <ul> | |
2551 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2552 * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> | |
2553 * </ul> | |
2554 * | |
2555 * @see #getAdvanced | |
2556 * @see #setAdvanced | |
2557 * | |
2558 * @since 3.1 | |
2559 */ | |
2560 public void setAlpha(int alpha) { | |
2561 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2562 data.alpha = alpha & 0xFF; | |
2563 data.state &= ~(BACKGROUND | FOREGROUND | FOREGROUND_FILL); | |
2564 | |
2565 } | |
2566 | |
2567 /** | |
2568 * Sets the receiver's anti-aliasing value to the parameter, | |
2569 * which must be one of <code>DWT.DEFAULT</code>, <code>DWT.OFF</code> | |
2570 * or <code>DWT.ON</code>. Note that this controls anti-aliasing for all | |
2571 * <em>non-text drawing</em> operations. | |
2572 * <p> | |
2573 * This operation requires the operating system's advanced | |
2574 * graphics subsystem which may not be available on some | |
2575 * platforms. | |
2576 * </p> | |
2577 * | |
2578 * @param antialias the anti-aliasing setting | |
2579 * | |
2580 * @exception IllegalArgumentException <ul> | |
2581 * <li>ERROR_INVALID_ARGUMENT - if the parameter is not one of <code>DWT.DEFAULT</code>, | |
2582 * <code>DWT.OFF</code> or <code>DWT.ON</code></li> | |
2583 * </ul> | |
2584 * @exception DWTException <ul> | |
2585 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2586 * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> | |
2587 * </ul> | |
2588 * | |
2589 * @see #getAdvanced | |
2590 * @see #setAdvanced | |
2591 * @see #setTextAntialias | |
2592 * | |
2593 * @since 3.1 | |
2594 */ | |
2595 public void setAntialias(int antialias) { | |
2596 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2597 bool mode = true; | |
2598 switch (antialias) { | |
2599 case DWT.DEFAULT: | |
2600 /* Printer is off by default */ | |
2601 // if (data.window is 0 && data.control is 0 && data.image is null) mode = false; | |
2602 mode = true; | |
2603 break; | |
2604 case DWT.OFF: mode = false; break; | |
2605 case DWT.ON: mode = true; break; | |
2606 default: | |
2607 DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
2608 } | |
2609 data.antialias = antialias; | |
2610 handle.setShouldAntialias(mode); | |
2611 } | |
2612 | |
2613 /** | |
2614 * Sets the background color. The background color is used | |
2615 * for fill operations and as the background color when text | |
2616 * is drawn. | |
2617 * | |
2618 * @param color the new background color for the receiver | |
2619 * | |
2620 * @exception IllegalArgumentException <ul> | |
2621 * <li>ERROR_NULL_ARGUMENT - if the color is null</li> | |
2622 * <li>ERROR_INVALID_ARGUMENT - if the color has been disposed</li> | |
2623 * </ul> | |
2624 * @exception DWTException <ul> | |
2625 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2626 * </ul> | |
2627 */ | |
2628 public void setBackground(Color color) { | |
2629 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2630 if (color is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | |
2631 if (color.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
2632 data.background = color.handle; | |
2633 data.backgroundPattern = null; | |
2634 data.state &= ~BACKGROUND; | |
2635 } | |
2636 | |
2637 /** | |
2638 * Sets the background pattern. The default value is <code>null</code>. | |
2639 * <p> | |
2640 * This operation requires the operating system's advanced | |
2641 * graphics subsystem which may not be available on some | |
2642 * platforms. | |
2643 * </p> | |
2644 * | |
2645 * @param pattern the new background pattern | |
2646 * | |
2647 * @exception IllegalArgumentException <ul> | |
2648 * <li>ERROR_INVALID_ARGUMENT - if the parameter has been disposed</li> | |
2649 * </ul> | |
2650 * @exception DWTException <ul> | |
2651 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2652 * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> | |
2653 * </ul> | |
2654 * | |
2655 * @see Pattern | |
2656 * @see #getAdvanced | |
2657 * @see #setAdvanced | |
2658 * | |
2659 * @since 3.1 | |
2660 */ | |
2661 public void setBackgroundPattern(Pattern pattern) { | |
2662 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2663 if (pattern !is null && pattern.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
2664 if (data.backgroundPattern is pattern) return; | |
2665 data.backgroundPattern = pattern; | |
2666 data.state &= ~BACKGROUND; | |
2667 } | |
2668 | |
2669 /** | |
2670 * Sets the area of the receiver which can be changed | |
2671 * by drawing operations to the rectangular area specified | |
2672 * by the arguments. | |
2673 * | |
2674 * @param x the x coordinate of the clipping rectangle | |
2675 * @param y the y coordinate of the clipping rectangle | |
2676 * @param width the width of the clipping rectangle | |
2677 * @param height the height of the clipping rectangle | |
2678 * | |
2679 * @exception DWTException <ul> | |
2680 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2681 * </ul> | |
2682 */ | |
2683 public void setClipping(int x, int y, int width, int height) { | |
2684 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2685 if (width < 0) { | |
2686 x = x + width; | |
2687 width = -width; | |
2688 } | |
2689 if (height < 0) { | |
2690 y = y + height; | |
2691 height = -height; | |
2692 } | |
2693 NSRect rect = new NSRect(); | |
2694 rect.x = x; | |
2695 rect.y = y; | |
2696 rect.width = width; | |
2697 rect.height = height; | |
2698 NSBezierPath path = NSBezierPath.bezierPathWithRect(rect); | |
2699 path.retain(); | |
2700 setClipping(path); | |
2701 } | |
2702 | |
2703 /** | |
2704 * Sets the area of the receiver which can be changed | |
2705 * by drawing operations to the path specified | |
2706 * by the argument. | |
2707 * <p> | |
2708 * This operation requires the operating system's advanced | |
2709 * graphics subsystem which may not be available on some | |
2710 * platforms. | |
2711 * </p> | |
2712 * | |
2713 * @param path the clipping path. | |
2714 * | |
2715 * @exception IllegalArgumentException <ul> | |
2716 * <li>ERROR_INVALID_ARGUMENT - if the path has been disposed</li> | |
2717 * </ul> | |
2718 * @exception DWTException <ul> | |
2719 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2720 * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> | |
2721 * </ul> | |
2722 * | |
2723 * @see Path | |
2724 * @see #getAdvanced | |
2725 * @see #setAdvanced | |
2726 * | |
2727 * @since 3.1 | |
2728 */ | |
2729 public void setClipping(Path path) { | |
2730 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2731 if (path !is null && path.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
2732 setClipping(new NSBezierPath(path.handle.copy().id)); | |
2733 } | |
2734 | |
2735 /** | |
2736 * Sets the area of the receiver which can be changed | |
2737 * by drawing operations to the rectangular area specified | |
2738 * by the argument. Specifying <code>null</code> for the | |
2739 * rectangle reverts the receiver's clipping area to its | |
2740 * original value. | |
2741 * | |
2742 * @param rect the clipping rectangle or <code>null</code> | |
2743 * | |
2744 * @exception DWTException <ul> | |
2745 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2746 * </ul> | |
2747 */ | |
2748 public void setClipping(Rectangle rect) { | |
2749 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2750 if (rect is null) { | |
2751 setClipping((NSBezierPath)null); | |
2752 } else { | |
2753 setClipping(rect.x, rect.y, rect.width, rect.height); | |
2754 } | |
2755 } | |
2756 | |
2757 /** | |
2758 * Sets the area of the receiver which can be changed | |
2759 * by drawing operations to the region specified | |
2760 * by the argument. Specifying <code>null</code> for the | |
2761 * region reverts the receiver's clipping area to its | |
2762 * original value. | |
2763 * | |
2764 * @param region the clipping region or <code>null</code> | |
2765 * | |
2766 * @exception IllegalArgumentException <ul> | |
2767 * <li>ERROR_INVALID_ARGUMENT - if the region has been disposed</li> | |
2768 * </ul> | |
2769 * @exception DWTException <ul> | |
2770 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2771 * </ul> | |
2772 */ | |
2773 public void setClipping(Region region) { | |
2774 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2775 if (region !is null && region.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
2776 setClipping(region !is null ? region.getPath() : null); | |
2777 } | |
2778 | |
2779 void setClipping(NSBezierPath path) { | |
2780 if (data.clipPath !is null) { | |
2781 data.clipPath.release(); | |
2782 data.clipPath = null; | |
2783 } | |
2784 if (path !is null) { | |
2785 data.clipPath = path; | |
2786 if (data.transform !is null) { | |
2787 data.clipPath.transformUsingAffineTransform(data.transform); | |
2788 } | |
2789 } | |
2790 data.state &= ~CLIPPING; | |
2791 } | |
2792 | |
2793 /** | |
2794 * Sets the receiver's fill rule to the parameter, which must be one of | |
2795 * <code>DWT.FILL_EVEN_ODD</code> or <code>DWT.FILL_WINDING</code>. | |
2796 * | |
2797 * @param rule the new fill rule | |
2798 * | |
2799 * @exception IllegalArgumentException <ul> | |
2800 * <li>ERROR_INVALID_ARGUMENT - if the rule is not one of <code>DWT.FILL_EVEN_ODD</code> | |
2801 * or <code>DWT.FILL_WINDING</code></li> | |
2802 * </ul> | |
2803 * @exception DWTException <ul> | |
2804 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2805 * </ul> | |
2806 * | |
2807 * @since 3.1 | |
2808 */ | |
2809 public void setFillRule(int rule) { | |
2810 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2811 switch (rule) { | |
2812 case DWT.FILL_WINDING: | |
2813 case DWT.FILL_EVEN_ODD: break; | |
2814 default: | |
2815 DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
2816 } | |
2817 data.fillRule = rule; | |
2818 data.path.setWindingRule(rule is DWT.FILL_WINDING ? OS.NSNonZeroWindingRule : OS.NSEvenOddWindingRule); | |
2819 } | |
2820 | |
2821 /** | |
2822 * Sets the font which will be used by the receiver | |
2823 * to draw and measure text to the argument. If the | |
2824 * argument is null, then a default font appropriate | |
2825 * for the platform will be used instead. | |
2826 * | |
2827 * @param font the new font for the receiver, or null to indicate a default font | |
2828 * | |
2829 * @exception IllegalArgumentException <ul> | |
2830 * <li>ERROR_INVALID_ARGUMENT - if the font has been disposed</li> | |
2831 * </ul> | |
2832 * @exception DWTException <ul> | |
2833 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2834 * </ul> | |
2835 */ | |
2836 public void setFont(Font font) { | |
2837 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2838 if (font !is null && font.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
2839 data.font = font !is null ? font : data.device.systemFont; | |
2840 data.state &= ~FONT; | |
2841 } | |
2842 | |
2843 /** | |
2844 * Sets the foreground color. The foreground color is used | |
2845 * for drawing operations including when text is drawn. | |
2846 * | |
2847 * @param color the new foreground color for the receiver | |
2848 * | |
2849 * @exception IllegalArgumentException <ul> | |
2850 * <li>ERROR_NULL_ARGUMENT - if the color is null</li> | |
2851 * <li>ERROR_INVALID_ARGUMENT - if the color has been disposed</li> | |
2852 * </ul> | |
2853 * @exception DWTException <ul> | |
2854 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2855 * </ul> | |
2856 */ | |
2857 public void setForeground(Color color) { | |
2858 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2859 if (color is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | |
2860 if (color.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
2861 data.foreground = color.handle; | |
2862 data.foregroundPattern = null; | |
2863 data.state &= ~(FOREGROUND | FOREGROUND_FILL); | |
2864 } | |
2865 | |
2866 /** | |
2867 * Sets the foreground pattern. The default value is <code>null</code>. | |
2868 * <p> | |
2869 * This operation requires the operating system's advanced | |
2870 * graphics subsystem which may not be available on some | |
2871 * platforms. | |
2872 * </p> | |
2873 * @param pattern the new foreground pattern | |
2874 * | |
2875 * @exception IllegalArgumentException <ul> | |
2876 * <li>ERROR_INVALID_ARGUMENT - if the parameter has been disposed</li> | |
2877 * </ul> | |
2878 * @exception DWTException <ul> | |
2879 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2880 * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> | |
2881 * </ul> | |
2882 * | |
2883 * @see Pattern | |
2884 * @see #getAdvanced | |
2885 * @see #setAdvanced | |
2886 * | |
2887 * @since 3.1 | |
2888 */ | |
2889 public void setForegroundPattern(Pattern pattern) { | |
2890 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2891 if (pattern !is null && pattern.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
2892 if (data.foregroundPattern is pattern) return; | |
2893 data.foregroundPattern = pattern; | |
2894 data.state &= ~(FOREGROUND | FOREGROUND_FILL); | |
2895 } | |
2896 | |
2897 /** | |
2898 * Sets the receiver's interpolation setting to the parameter, which | |
2899 * must be one of <code>DWT.DEFAULT</code>, <code>DWT.NONE</code>, | |
2900 * <code>DWT.LOW</code> or <code>DWT.HIGH</code>. | |
2901 * <p> | |
2902 * This operation requires the operating system's advanced | |
2903 * graphics subsystem which may not be available on some | |
2904 * platforms. | |
2905 * </p> | |
2906 * | |
2907 * @param interpolation the new interpolation setting | |
2908 * | |
2909 * @exception IllegalArgumentException <ul> | |
2910 * <li>ERROR_INVALID_ARGUMENT - if the rule is not one of <code>DWT.DEFAULT</code>, | |
2911 * <code>DWT.NONE</code>, <code>DWT.LOW</code> or <code>DWT.HIGH</code> | |
2912 * </ul> | |
2913 * @exception DWTException <ul> | |
2914 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2915 * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> | |
2916 * </ul> | |
2917 * | |
2918 * @see #getAdvanced | |
2919 * @see #setAdvanced | |
2920 * | |
2921 * @since 3.1 | |
2922 */ | |
2923 public void setInterpolation(int interpolation) { | |
2924 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2925 int quality = 0; | |
2926 switch (interpolation) { | |
2927 case DWT.DEFAULT: quality = OS.NSImageInterpolationDefault; break; | |
2928 case DWT.NONE: quality = OS.NSImageInterpolationNone; break; | |
2929 case DWT.LOW: quality = OS.NSImageInterpolationLow; break; | |
2930 case DWT.HIGH: quality = OS.NSImageInterpolationHigh; break; | |
2931 default: | |
2932 DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
2933 } | |
2934 handle.setImageInterpolation(quality); | |
2935 } | |
2936 | |
2937 /** | |
2938 * Sets the receiver's line attributes. | |
2939 * <p> | |
2940 * This operation requires the operating system's advanced | |
2941 * graphics subsystem which may not be available on some | |
2942 * platforms. | |
2943 * </p> | |
2944 * @param attributes the line attributes | |
2945 * | |
2946 * @exception IllegalArgumentException <ul> | |
2947 * <li>ERROR_NULL_ARGUMENT - if the attributes is null</li> | |
2948 * <li>ERROR_INVALID_ARGUMENT - if any of the line attributes is not valid</li> | |
2949 * </ul> | |
2950 * @exception DWTException <ul> | |
2951 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
2952 * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> | |
2953 * </ul> | |
2954 * | |
2955 * @see LineAttributes | |
2956 * @see #getAdvanced | |
2957 * @see #setAdvanced | |
2958 * | |
2959 * @since 3.3 | |
2960 */ | |
2961 public void setLineAttributes(LineAttributes attributes) { | |
2962 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
2963 if (attributes is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | |
2964 int mask = 0; | |
2965 float lineWidth = attributes.width; | |
2966 if (lineWidth !is data.lineWidth) { | |
2967 mask |= LINE_WIDTH | DRAW_OFFSET; | |
2968 } | |
2969 int lineStyle = attributes.style; | |
2970 if (lineStyle !is data.lineStyle) { | |
2971 mask |= LINE_STYLE; | |
2972 switch (lineStyle) { | |
2973 case DWT.LINE_SOLID: | |
2974 case DWT.LINE_DASH: | |
2975 case DWT.LINE_DOT: | |
2976 case DWT.LINE_DASHDOT: | |
2977 case DWT.LINE_DASHDOTDOT: | |
2978 break; | |
2979 case DWT.LINE_CUSTOM: | |
2980 if (attributes.dash is null) lineStyle = DWT.LINE_SOLID; | |
2981 break; | |
2982 default: | |
2983 DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
2984 } | |
2985 } | |
2986 int join = attributes.join; | |
2987 if (join !is data.lineJoin) { | |
2988 mask |= LINE_JOIN; | |
2989 switch (join) { | |
2990 case DWT.CAP_ROUND: | |
2991 case DWT.CAP_FLAT: | |
2992 case DWT.CAP_SQUARE: | |
2993 break; | |
2994 default: | |
2995 DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
2996 } | |
2997 } | |
2998 int cap = attributes.cap; | |
2999 if (cap !is data.lineCap) { | |
3000 mask |= LINE_CAP; | |
3001 switch (cap) { | |
3002 case DWT.JOIN_MITER: | |
3003 case DWT.JOIN_ROUND: | |
3004 case DWT.JOIN_BEVEL: | |
3005 break; | |
3006 default: | |
3007 DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
3008 } | |
3009 } | |
3010 float[] dashes = attributes.dash; | |
3011 float[] lineDashes = data.lineDashes; | |
3012 if (dashes !is null && dashes.length > 0) { | |
3013 bool changed = lineDashes is null || lineDashes.length !is dashes.length; | |
3014 for (int i = 0; i < dashes.length; i++) { | |
3015 float dash = dashes[i]; | |
3016 if (dash <= 0) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
3017 if (!changed && lineDashes[i] !is dash) changed = true; | |
3018 } | |
3019 if (changed) { | |
3020 float[] newDashes = new float[dashes.length]; | |
3021 System.arraycopy(dashes, 0, newDashes, 0, dashes.length); | |
3022 dashes = newDashes; | |
3023 mask |= LINE_STYLE; | |
3024 } else { | |
3025 dashes = lineDashes; | |
3026 } | |
3027 } else { | |
3028 if (lineDashes !is null && lineDashes.length > 0) { | |
3029 mask |= LINE_STYLE; | |
3030 } else { | |
3031 dashes = lineDashes; | |
3032 } | |
3033 } | |
3034 float dashOffset = attributes.dashOffset; | |
3035 if (dashOffset !is data.lineDashesOffset) { | |
3036 mask |= LINE_STYLE; | |
3037 } | |
3038 float miterLimit = attributes.miterLimit; | |
3039 if (miterLimit !is data.lineMiterLimit) { | |
3040 mask |= LINE_MITERLIMIT; | |
3041 } | |
3042 if (mask is 0) return; | |
3043 data.lineWidth = lineWidth; | |
3044 data.lineStyle = lineStyle; | |
3045 data.lineCap = cap; | |
3046 data.lineJoin = join; | |
3047 data.lineDashes = dashes; | |
3048 data.lineDashesOffset = dashOffset; | |
3049 data.lineMiterLimit = miterLimit; | |
3050 data.state &= ~mask; | |
3051 } | |
3052 | |
3053 /** | |
3054 * Sets the receiver's line cap style to the argument, which must be one | |
3055 * of the constants <code>DWT.CAP_FLAT</code>, <code>DWT.CAP_ROUND</code>, | |
3056 * or <code>DWT.CAP_SQUARE</code>. | |
3057 * | |
3058 * @param cap the cap style to be used for drawing lines | |
3059 * | |
3060 * @exception IllegalArgumentException <ul> | |
3061 * <li>ERROR_INVALID_ARGUMENT - if the style is not valid</li> | |
3062 * </ul> | |
3063 * @exception DWTException <ul> | |
3064 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
3065 * </ul> | |
3066 * | |
3067 * @since 3.1 | |
3068 */ | |
3069 public void setLineCap(int cap) { | |
3070 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
3071 if (data.lineCap is cap) return; | |
3072 switch (cap) { | |
3073 case DWT.CAP_ROUND: | |
3074 case DWT.CAP_FLAT: | |
3075 case DWT.CAP_SQUARE: | |
3076 break; | |
3077 default: | |
3078 DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
3079 } | |
3080 data.lineCap = cap; | |
3081 data.state &= ~LINE_CAP; | |
3082 } | |
3083 | |
3084 /** | |
3085 * Sets the receiver's line dash style to the argument. The default | |
3086 * value is <code>null</code>. If the argument is not <code>null</code>, | |
3087 * the receiver's line style is set to <code>DWT.LINE_CUSTOM</code>, otherwise | |
3088 * it is set to <code>DWT.LINE_SOLID</code>. | |
3089 * | |
3090 * @param dashes the dash style to be used for drawing lines | |
3091 * | |
3092 * @exception IllegalArgumentException <ul> | |
3093 * <li>ERROR_INVALID_ARGUMENT - if any of the values in the array is less than or equal 0</li> | |
3094 * </ul> | |
3095 * @exception DWTException <ul> | |
3096 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
3097 * </ul> | |
3098 * | |
3099 * @since 3.1 | |
3100 */ | |
3101 public void setLineDash(int[] dashes) { | |
3102 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
3103 float[] lineDashes = data.lineDashes; | |
3104 if (dashes !is null && dashes.length > 0) { | |
3105 bool changed = data.lineStyle !is DWT.LINE_CUSTOM || lineDashes is null || lineDashes.length !is dashes.length; | |
3106 for (int i = 0; i < dashes.length; i++) { | |
3107 int dash = dashes[i]; | |
3108 if (dash <= 0) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
3109 if (!changed && lineDashes[i] !is dash) changed = true; | |
3110 } | |
3111 if (!changed) return; | |
3112 data.lineDashes = new float[dashes.length]; | |
3113 for (int i = 0; i < dashes.length; i++) { | |
3114 data.lineDashes[i] = dashes[i]; | |
3115 } | |
3116 data.lineStyle = DWT.LINE_CUSTOM; | |
3117 } else { | |
3118 if (data.lineStyle is DWT.LINE_SOLID && (lineDashes is null || lineDashes.length is 0)) return; | |
3119 data.lineDashes = null; | |
3120 data.lineStyle = DWT.LINE_SOLID; | |
3121 } | |
3122 data.state &= ~LINE_STYLE; | |
3123 } | |
3124 | |
3125 /** | |
3126 * Sets the receiver's line join style to the argument, which must be one | |
3127 * of the constants <code>DWT.JOIN_MITER</code>, <code>DWT.JOIN_ROUND</code>, | |
3128 * or <code>DWT.JOIN_BEVEL</code>. | |
3129 * | |
3130 * @param join the join style to be used for drawing lines | |
3131 * | |
3132 * @exception IllegalArgumentException <ul> | |
3133 * <li>ERROR_INVALID_ARGUMENT - if the style is not valid</li> | |
3134 * </ul> | |
3135 * @exception DWTException <ul> | |
3136 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
3137 * </ul> | |
3138 * | |
3139 * @since 3.1 | |
3140 */ | |
3141 public void setLineJoin(int join) { | |
3142 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
3143 if (data.lineJoin is join) return; | |
3144 switch (join) { | |
3145 case DWT.JOIN_MITER: | |
3146 case DWT.JOIN_ROUND: | |
3147 case DWT.JOIN_BEVEL: | |
3148 break; | |
3149 default: | |
3150 DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
3151 } | |
3152 data.lineJoin = join; | |
3153 data.state &= ~LINE_JOIN; | |
3154 } | |
3155 | |
3156 /** | |
3157 * Sets the receiver's line style to the argument, which must be one | |
3158 * of the constants <code>DWT.LINE_SOLID</code>, <code>DWT.LINE_DASH</code>, | |
3159 * <code>DWT.LINE_DOT</code>, <code>DWT.LINE_DASHDOT</code> or | |
3160 * <code>DWT.LINE_DASHDOTDOT</code>. | |
3161 * | |
3162 * @param lineStyle the style to be used for drawing lines | |
3163 * | |
3164 * @exception IllegalArgumentException <ul> | |
3165 * <li>ERROR_INVALID_ARGUMENT - if the style is not valid</li> | |
3166 * </ul> | |
3167 * @exception DWTException <ul> | |
3168 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
3169 * </ul> | |
3170 */ | |
3171 public void setLineStyle(int lineStyle) { | |
3172 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
3173 if (data.lineStyle is lineStyle) return; | |
3174 switch (lineStyle) { | |
3175 case DWT.LINE_SOLID: | |
3176 case DWT.LINE_DASH: | |
3177 case DWT.LINE_DOT: | |
3178 case DWT.LINE_DASHDOT: | |
3179 case DWT.LINE_DASHDOTDOT: | |
3180 break; | |
3181 case DWT.LINE_CUSTOM: | |
3182 if (data.lineDashes is null) lineStyle = DWT.LINE_SOLID; | |
3183 break; | |
3184 default: | |
3185 DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
3186 } | |
3187 data.lineStyle = lineStyle; | |
3188 data.state &= ~LINE_STYLE; | |
3189 } | |
3190 | |
3191 /** | |
3192 * Sets the width that will be used when drawing lines | |
3193 * for all of the figure drawing operations (that is, | |
3194 * <code>drawLine</code>, <code>drawRectangle</code>, | |
3195 * <code>drawPolyline</code>, and so forth. | |
3196 * <p> | |
3197 * Note that line width of zero is used as a hint to | |
3198 * indicate that the fastest possible line drawing | |
3199 * algorithms should be used. This means that the | |
3200 * output may be different from line width one. | |
3201 * </p> | |
3202 * | |
3203 * @param lineWidth the width of a line | |
3204 * | |
3205 * @exception DWTException <ul> | |
3206 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
3207 * </ul> | |
3208 */ | |
3209 public void setLineWidth(int lineWidth) { | |
3210 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
3211 if (data.lineWidth is lineWidth) return; | |
3212 data.lineWidth = lineWidth; | |
3213 data.state &= ~(LINE_WIDTH | DRAW_OFFSET); | |
3214 } | |
3215 | |
3216 /** | |
3217 * If the argument is <code>true</code>, puts the receiver | |
3218 * in a drawing mode where the resulting color in the destination | |
3219 * is the <em>exclusive or</em> of the color values in the source | |
3220 * and the destination, and if the argument is <code>false</code>, | |
3221 * puts the receiver in a drawing mode where the destination color | |
3222 * is replaced with the source color value. | |
3223 * <p> | |
3224 * Note that this mode in fundamentally unsupportable on certain | |
3225 * platforms, notably Carbon (Mac OS X). Clients that want their | |
3226 * code to run on all platforms need to avoid this method. | |
3227 * </p> | |
3228 * | |
3229 * @param xor if <code>true</code>, then <em>xor</em> mode is used, otherwise <em>source copy</em> mode is used | |
3230 * | |
3231 * @exception DWTException <ul> | |
3232 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
3233 * </ul> | |
3234 * | |
3235 * @deprecated this functionality is not supported on some platforms | |
3236 */ | |
3237 public void setXORMode(bool xor) { | |
3238 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
3239 data.xorMode = xor; | |
3240 } | |
3241 | |
3242 /** | |
3243 * Sets the receiver's text anti-aliasing value to the parameter, | |
3244 * which must be one of <code>DWT.DEFAULT</code>, <code>DWT.OFF</code> | |
3245 * or <code>DWT.ON</code>. Note that this controls anti-aliasing only | |
3246 * for all <em>text drawing</em> operations. | |
3247 * <p> | |
3248 * This operation requires the operating system's advanced | |
3249 * graphics subsystem which may not be available on some | |
3250 * platforms. | |
3251 * </p> | |
3252 * | |
3253 * @param antialias the anti-aliasing setting | |
3254 * | |
3255 * @exception IllegalArgumentException <ul> | |
3256 * <li>ERROR_INVALID_ARGUMENT - if the parameter is not one of <code>DWT.DEFAULT</code>, | |
3257 * <code>DWT.OFF</code> or <code>DWT.ON</code></li> | |
3258 * </ul> | |
3259 * @exception DWTException <ul> | |
3260 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
3261 * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> | |
3262 * </ul> | |
3263 * | |
3264 * @see #getAdvanced | |
3265 * @see #setAdvanced | |
3266 * @see #setAntialias | |
3267 * | |
3268 * @since 3.1 | |
3269 */ | |
3270 public void setTextAntialias(int antialias) { | |
3271 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
3272 switch (antialias) { | |
3273 case DWT.DEFAULT: | |
3274 case DWT.OFF: | |
3275 case DWT.ON: | |
3276 break; | |
3277 default: | |
3278 DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
3279 } | |
3280 data.textAntialias = antialias; | |
3281 } | |
3282 | |
3283 /** | |
3284 * Sets the transform that is currently being used by the receiver. If | |
3285 * the argument is <code>null</code>, the current transform is set to | |
3286 * the identity transform. | |
3287 * <p> | |
3288 * This operation requires the operating system's advanced | |
3289 * graphics subsystem which may not be available on some | |
3290 * platforms. | |
3291 * </p> | |
3292 * | |
3293 * @param transform the transform to set | |
3294 * | |
3295 * @exception IllegalArgumentException <ul> | |
3296 * <li>ERROR_INVALID_ARGUMENT - if the parameter has been disposed</li> | |
3297 * </ul> | |
3298 * @exception DWTException <ul> | |
3299 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
3300 * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> | |
3301 * </ul> | |
3302 * | |
3303 * @see Transform | |
3304 * @see #getAdvanced | |
3305 * @see #setAdvanced | |
3306 * | |
3307 * @since 3.1 | |
3308 */ | |
3309 public void setTransform(Transform transform) { | |
3310 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
3311 if (transform !is null && transform.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); | |
3312 if (transform !is null) { | |
3313 if (data.transform !is null) data.transform.release(); | |
3314 if (data.inverseTransform !is null) data.inverseTransform.release(); | |
3315 data.transform = ((NSAffineTransform)new NSAffineTransform().alloc()).initWithTransform(transform.handle); | |
3316 data.inverseTransform = ((NSAffineTransform)new NSAffineTransform().alloc()).initWithTransform(transform.handle); | |
3317 NSAffineTransformStruct struct = data.inverseTransform.transformStruct(); | |
3318 if ((struct.m11 * struct.m22 - struct.m12 * struct.m21) !is 0) { | |
3319 data.inverseTransform.invert(); | |
3320 } | |
3321 } else { | |
3322 data.transform = data.inverseTransform = null; | |
3323 } | |
3324 data.state &= ~(TRANSFORM | DRAW_OFFSET); | |
3325 } | |
3326 | |
3327 /** | |
3328 * Returns the extent of the given string. No tab | |
3329 * expansion or carriage return processing will be performed. | |
3330 * <p> | |
3331 * The <em>extent</em> of a string is the width and height of | |
3332 * the rectangular area it would cover if drawn in a particular | |
3333 * font (in this case, the current font in the receiver). | |
3334 * </p> | |
3335 * | |
3336 * @param string the string to measure | |
3337 * @return a point containing the extent of the string | |
3338 * | |
3339 * @exception IllegalArgumentException <ul> | |
3340 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | |
3341 * </ul> | |
3342 * @exception DWTException <ul> | |
3343 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
3344 * </ul> | |
3345 */ | |
3346 public Point stringExtent(String string) { | |
3347 return textExtent(string, 0); | |
3348 } | |
3349 | |
3350 /** | |
3351 * Returns the extent of the given string. Tab expansion and | |
3352 * carriage return processing are performed. | |
3353 * <p> | |
3354 * The <em>extent</em> of a string is the width and height of | |
3355 * the rectangular area it would cover if drawn in a particular | |
3356 * font (in this case, the current font in the receiver). | |
3357 * </p> | |
3358 * | |
3359 * @param string the string to measure | |
3360 * @return a point containing the extent of the string | |
3361 * | |
3362 * @exception IllegalArgumentException <ul> | |
3363 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | |
3364 * </ul> | |
3365 * @exception DWTException <ul> | |
3366 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
3367 * </ul> | |
3368 */ | |
3369 public Point textExtent(String string) { | |
3370 return textExtent(string, DWT.DRAW_DELIMITER | DWT.DRAW_TAB); | |
3371 } | |
3372 | |
3373 /** | |
3374 * Returns the extent of the given string. Tab expansion, line | |
3375 * delimiter and mnemonic processing are performed according to | |
3376 * the specified flags, which can be a combination of: | |
3377 * <dl> | |
3378 * <dt><b>DRAW_DELIMITER</b></dt> | |
3379 * <dd>draw multiple lines</dd> | |
3380 * <dt><b>DRAW_TAB</b></dt> | |
3381 * <dd>expand tabs</dd> | |
3382 * <dt><b>DRAW_MNEMONIC</b></dt> | |
3383 * <dd>underline the mnemonic character</dd> | |
3384 * <dt><b>DRAW_TRANSPARENT</b></dt> | |
3385 * <dd>transparent background</dd> | |
3386 * </dl> | |
3387 * <p> | |
3388 * The <em>extent</em> of a string is the width and height of | |
3389 * the rectangular area it would cover if drawn in a particular | |
3390 * font (in this case, the current font in the receiver). | |
3391 * </p> | |
3392 * | |
3393 * @param string the string to measure | |
3394 * @param flags the flags specifying how to process the text | |
3395 * @return a point containing the extent of the string | |
3396 * | |
3397 * @exception IllegalArgumentException <ul> | |
3398 * <li>ERROR_NULL_ARGUMENT - if the string is null</li> | |
3399 * </ul> | |
3400 * @exception DWTException <ul> | |
3401 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> | |
3402 * </ul> | |
3403 */ | |
3404 public Point textExtent(String string, int flags) { | |
3405 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); | |
3406 if (string is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); | |
3407 checkGC(FONT); | |
3408 NSAttributedString str = createString(string, flags); | |
3409 NSSize size = str.size(); | |
3410 return new Point((int)size.width, (int)size.height); | |
3411 } | |
3412 | |
3413 /** | |
3414 * Returns a string containing a concise, human-readable | |
3415 * description of the receiver. | |
3416 * | |
3417 * @return a string representation of the receiver | |
3418 */ | |
3419 public String toString () { | |
3420 if (isDisposed()) return "GC {*DISPOSED*}"; | |
3421 return "GC {" + handle + "}"; | |
3422 } | |
3423 | |
3424 } |