/*******************************************************************************
 * Copyright (c) 2000, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.graphics;

import java.util.*;

import org.eclipse.swt.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.cocoa.*;

/**
 * Class <code>GC</code> is where all of the drawing capabilities that are
 * supported by SWT are located. Instances are used to draw on either an
 * <code>Image</code>, a <code>Control</code>, or directly on a <code>Display</code>.
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>LEFT_TO_RIGHT, RIGHT_TO_LEFT</dd>
 * </dl>
 *
 * <p>
 * The SWT drawing coordinate system is the two-dimensional space with the origin
 * (0,0) at the top left corner of the drawing area and with (x,y) values increasing
 * to the right and downward respectively.
 * </p>
 *
 * <p>
 * The result of drawing on an image that was created with an indexed
 * palette using a color that is not in the palette is platform specific.
 * Some platforms will match to the nearest color while other will draw
 * the color itself. This happens because the allocated image might use
 * a direct palette on platforms that do not support indexed palette.
 * </p>
 *
 * <p>
 * Application code must explicitly invoke the <code>GC.dispose()</code>
 * method to release the operating system resources managed by each instance
 * when those instances are no longer required. This is <em>particularly</em>
 * important on Windows95 and Windows98 where the operating system has a limited
 * number of device contexts available.
 * </p>
 *
 * <p>
 * Note: Only one of LEFT_TO_RIGHT and RIGHT_TO_LEFT may be specified.
 * </p>
 *
 * @see org.eclipse.swt.events.PaintEvent
 * @see <a href="http://www.eclipse.org/swt/snippets/#gc">GC snippets</a>
 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Examples: GraphicsExample, PaintExample</a>
 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
 */
public final class GC extends Resource {
	/**
	 * the handle to the OS device context
	 * (Warning: This field is platform dependent)
	 * <p>
	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
	 * public API. It is marked public only so that it can be shared
	 * within the packages provided by SWT. It is not available on all
	 * platforms and should never be accessed from application code.
	 * </p>
	 *
	 * @noreference This field is not intended to be referenced by clients.
	 */
	public NSGraphicsContext handle;

	Drawable drawable;
	GCData data;
	GCTextData.Cache textDataCache = new GCTextData.Cache(20);

	CGPathElement element;
	int count, typeCount;
	byte[] types;
	double[] points;
	double [] point;

	static final int TAB_COUNT = 32;

	final static int FOREGROUND = 1 << 0;
	final static int BACKGROUND = 1 << 1;
	final static int FONT = 1 << 2;
	final static int LINE_STYLE = 1 << 3;
	final static int LINE_CAP = 1 << 4;
	final static int LINE_JOIN = 1 << 5;
	final static int LINE_WIDTH = 1 << 6;
	final static int LINE_MITERLIMIT = 1 << 7;
	final static int FOREGROUND_FILL = 1 << 8;
	final static int DRAW_OFFSET = 1 << 9;
	final static int CLIPPING = 1 << 10;
	final static int TRANSFORM = 1 << 11;
	final static int VISIBLE_REGION = 1 << 12;
	final static int DRAW = CLIPPING | TRANSFORM | FOREGROUND | LINE_WIDTH | LINE_STYLE  | LINE_CAP  | LINE_JOIN | LINE_MITERLIMIT | DRAW_OFFSET;
	final static int FILL = CLIPPING | TRANSFORM | BACKGROUND;

	static final float[] LINE_DOT = new float[]{1, 1};
	static final float[] LINE_DASH = new float[]{3, 1};
	static final float[] LINE_DASHDOT = new float[]{3, 1, 1, 1};
	static final float[] LINE_DASHDOTDOT = new float[]{3, 1, 1, 1, 1, 1};
	static final float[] LINE_DOT_ZERO = new float[]{3, 3};
	static final float[] LINE_DASH_ZERO = new float[]{18, 6};
	static final float[] LINE_DASHDOT_ZERO = new float[]{9, 6, 3, 6};
	static final float[] LINE_DASHDOTDOT_ZERO = new float[]{9, 3, 3, 3, 3, 3};

	/**
	 * Instances of this class are descriptions of GCs for text drawing in terms of
	 * platform-specific data fields. Can be cached to improve repeat render
	 * performance.
	 */
	private static class GCTextData {
		private NSPoint pt = new NSPoint();
		private NSLayoutManager layoutManager;
		private NSTextStorage textStorage;
		private NSRange range;

		/**
		 * Simple {@link GCTextData} cache limited to a set number of items.
		 */
		private static class Cache {
			private final int cacheSize;
			private final Map<String, GCTextData> cache = new LinkedHashMap<String, GCTextData>() {
				private static final long serialVersionUID = 1L;

				@Override
				protected boolean removeEldestEntry(Map.Entry<String, GCTextData> eldest) {
					if (size() >= cacheSize) {
						((GCTextData) eldest.getValue()).release();
						return true;
					}
					return false;
				};
			};

			public Cache(int cacheSize) {
				this.cacheSize = cacheSize;
			}

			public void release() {
				for (GCTextData data : cache.values()) {
					data.release();
				}
				cache.clear();
			}

			public GCTextData get(String string) {
				return cache.get(string);
			}

			public void put(String string, GCTextData data) {
				cache.put(string, data);
			}
		}

		public GCTextData(NSAttributedString attribStr) {
			NSSize size = new NSSize();
			size.width = OS.MAX_TEXT_CONTAINER_SIZE;
			size.height = OS.MAX_TEXT_CONTAINER_SIZE;
			NSTextStorage textStorage = (NSTextStorage) new NSTextStorage().alloc().init();
			NSLayoutManager layoutManager = (NSLayoutManager) new NSLayoutManager().alloc().init();
			layoutManager.setBackgroundLayoutEnabled(NSThread.isMainThread());
			NSTextContainer textContainer = (NSTextContainer) new NSTextContainer().alloc();
			textContainer = textContainer.initWithContainerSize(size);
			textContainer.setLineFragmentPadding(0);
			textStorage.addLayoutManager(layoutManager);
			layoutManager.addTextContainer(textContainer);
			layoutManager.release();
			textContainer.release();
			this.layoutManager = layoutManager;
			this.textStorage = textStorage;
			textStorage.setAttributedString(attribStr);
			this.range = layoutManager.glyphRangeForTextContainer(textContainer);
		}

		public void release() {
			if (textStorage != null) textStorage.release();
			textStorage = null;
			layoutManager = null;
		}

		public void draw(int x, int y) {
			pt.x = x;
			pt.y = y;
			layoutManager.drawGlyphsForGlyphRange(range, pt);
		}
	}

GC() {
}

/**
 * Constructs a new instance of this class which has been
 * configured to draw on the specified drawable. Sets the
 * foreground color, background color and font in the GC
 * to match those in the drawable.
 * <p>
 * You must dispose the graphics context when it is no longer required.
 * </p>
 * @param drawable the drawable to draw on
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the drawable is null</li>
 *    <li>ERROR_NULL_ARGUMENT - if there is no current device</li>
 *    <li>ERROR_INVALID_ARGUMENT
 *          - if the drawable is an image that is not a bitmap or an icon
 *          - if the drawable is an image or printer that is already selected
 *            into another graphics context</li>
 * </ul>
 * @exception SWTError <ul>
 *    <li>ERROR_NO_HANDLES if a handle could not be obtained for GC creation</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS if not called from the thread that created the drawable</li>
 * </ul>
 * @see #dispose()
 */
public GC(Drawable drawable) {
	this(drawable, 0);
}

/**
 * Constructs a new instance of this class which has been
 * configured to draw on the specified drawable. Sets the
 * foreground color, background color and font in the GC
 * to match those in the drawable.
 * <p>
 * You must dispose the graphics context when it is no longer required.
 * </p>
 *
 * @param drawable the drawable to draw on
 * @param style the style of GC to construct
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the drawable is null</li>
 *    <li>ERROR_NULL_ARGUMENT - if there is no current device</li>
 *    <li>ERROR_INVALID_ARGUMENT
 *          - if the drawable is an image that is not a bitmap or an icon
 *          - if the drawable is an image or printer that is already selected
 *            into another graphics context</li>
 * </ul>
 * @exception SWTError <ul>
 *    <li>ERROR_NO_HANDLES if a handle could not be obtained for GC creation</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS if not called from the thread that created the drawable</li>
 * </ul>
 *
 * @see #dispose()
 *
 * @since 2.1.2
 */
public GC(Drawable drawable, int style) {
	if (drawable == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	NSAutoreleasePool pool = null;
	if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
	try {
		GCData data = new GCData();
		data.style = checkStyle(style);
		long contextId = drawable.internal_new_GC(data);
		Device device = data.device;
		if (device == null) device = Device.getDevice();
		if (device == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
		this.device = data.device = device;
		init(drawable, data, contextId);
		init();
	} finally {
		if (pool != null) pool.release();
	}
}

static int checkStyle (int style) {
	if ((style & SWT.LEFT_TO_RIGHT) != 0) style &= ~SWT.RIGHT_TO_LEFT;
	return style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
}

/**
 * Invokes platform specific functionality to allocate a new graphics context.
 * <p>
 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
 * API for <code>GC</code>. It is marked public only so that it
 * can be shared within the packages provided by SWT. It is not
 * available on all platforms, and should never be called from
 * application code.
 * </p>
 *
 * @param drawable the Drawable for the receiver.
 * @param data the data for the receiver.
 *
 * @return a new <code>GC</code>
 *
 * @noreference This method is not intended to be referenced by clients.
 */
public static GC cocoa_new(Drawable drawable, GCData data) {
	GC gc = new GC();
	long context = drawable.internal_new_GC(data);
	gc.device = data.device;
	gc.init(drawable, data, context);
	return gc;
}

long applierFunc(long info, long elementPtr) {
	OS.memmove(element, elementPtr, CGPathElement.sizeof);
	int type = 0, length = 1;
	switch (element.type) {
		case OS.kCGPathElementMoveToPoint: type = SWT.PATH_MOVE_TO; break;
		case OS.kCGPathElementAddLineToPoint: type = SWT.PATH_LINE_TO; break;
		case OS.kCGPathElementAddQuadCurveToPoint: type = SWT.PATH_QUAD_TO; length = 2; break;
		case OS.kCGPathElementAddCurveToPoint: type = SWT.PATH_CUBIC_TO; length = 3; break;
		case OS.kCGPathElementCloseSubpath: type = SWT.PATH_CLOSE; length = 0; break;
	}
	if (types != null) {
		types[typeCount] = (byte)type;
		if (length > 0) {
			C.memmove(point, element.points, length * CGPoint.sizeof);
			System.arraycopy(point, 0, points, count, length * 2);
		}
	}
	typeCount++;
	count += length * 2;
	return 0;
}

NSAutoreleasePool checkGC (int mask) {
	NSAutoreleasePool pool = null;
	if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
	if (data.flippedContext != null && !handle.isEqual(NSGraphicsContext.currentContext())) {
		data.restoreContext = true;
		NSGraphicsContext.static_saveGraphicsState();
		NSGraphicsContext.setCurrentContext(handle);
	}
	if ((mask & (CLIPPING | TRANSFORM)) != 0) {
		NSView view = data.view;
		if ((data.state & CLIPPING) == 0 || (data.state & TRANSFORM) == 0 || (data.state & VISIBLE_REGION) == 0) {
			boolean antialias = handle.shouldAntialias();
			handle.restoreGraphicsState();
			handle.saveGraphicsState();
			handle.setShouldAntialias(antialias);
			if (view != null && (data.paintRect == null || !view.isFlipped())) {
				NSAffineTransform transform = NSAffineTransform.transform();
				NSRect rect = view.convertRect_toView_(view.bounds(), null);
				if (data.paintRect == null) {
					transform.translateXBy(rect.x, rect.y + rect.height);
				} else {
					transform.translateXBy(0, rect.height);
				}
				transform.scaleXBy(1, -1);
				transform.concat();
				if (data.visibleRgn != 0) {
					if (data.visiblePath == null || (data.state & VISIBLE_REGION) == 0) {
						if (data.visiblePath != null) data.visiblePath.release();
						data.visiblePath = Region.cocoa_new(device, data.visibleRgn).getPath();
					}
					data.visiblePath.addClip();
					data.state |= VISIBLE_REGION;
				}
			}
			if (data.clipPath != null) data.clipPath.addClip();
			if (data.transform != null) data.transform.concat();
			mask &= ~(TRANSFORM | CLIPPING);
			data.state |= TRANSFORM | CLIPPING;
			data.state &= ~(BACKGROUND | FOREGROUND);
		}
	}

	OS.CGContextSetBlendMode(handle.graphicsPort(), data.xorMode ? OS.kCGBlendModeDifference : OS.kCGBlendModeNormal);

	int state = data.state;
	if ((state & mask) == mask) return pool;
	state = (state ^ mask) & mask;
	data.state |= mask;

	if ((state & FOREGROUND) != 0) {
		Pattern pattern = data.foregroundPattern;
		if (pattern != null) {
			if (pattern.color != null) pattern.color.setStroke();
		} else {
			double [] color = data.foreground;
			if (data.fg != null) data.fg.release();
			NSColor fg = data.fg = NSColor.colorWithDeviceRed(color[0], color[1], color[2], data.alpha / 255f);
			fg.retain();
			fg.setStroke();
		}
	}
	if ((state & FOREGROUND_FILL) != 0) {
		Pattern pattern = data.foregroundPattern;
		if (pattern != null) {
			if (pattern.color != null) pattern.color.setFill();
		} else {
			double [] color = data.foreground;
			if (data.fg != null) data.fg.release();
			NSColor fg = data.fg = NSColor.colorWithDeviceRed(color[0], color[1], color[2], data.alpha / 255f);
			fg.retain();
			fg.setFill();
		}
		data.state &= ~BACKGROUND;
	}
	if ((state & BACKGROUND) != 0) {
		Pattern pattern = data.backgroundPattern;
		if (pattern != null) {
			if (pattern.color != null) pattern.color.setFill();
		} else {
			double [] color = data.background;
			if (data.bg != null) data.bg.release();
			NSColor bg = data.bg = NSColor.colorWithDeviceRed(color[0], color[1], color[2], data.alpha / 255f);
			bg.retain();
			bg.setFill();
		}
		data.state &= ~FOREGROUND_FILL;
	}
	NSBezierPath path = data.path;
	if ((state & LINE_WIDTH) != 0) {
		path.setLineWidth(data.lineWidth == 0 ?  1 : data.lineWidth);
		switch (data.lineStyle) {
			case SWT.LINE_DOT:
			case SWT.LINE_DASH:
			case SWT.LINE_DASHDOT:
			case SWT.LINE_DASHDOTDOT:
				state |= LINE_STYLE;
		}
	}
	if ((state & LINE_STYLE) != 0) {
		float[] dashes = null;
		float width = data.lineWidth;
		switch (data.lineStyle) {
			case SWT.LINE_SOLID: break;
			case SWT.LINE_DASH: dashes = width != 0 ? LINE_DASH : LINE_DASH_ZERO; break;
			case SWT.LINE_DOT: dashes = width != 0 ? LINE_DOT : LINE_DOT_ZERO; break;
			case SWT.LINE_DASHDOT: dashes = width != 0 ? LINE_DASHDOT : LINE_DASHDOT_ZERO; break;
			case SWT.LINE_DASHDOTDOT: dashes = width != 0 ? LINE_DASHDOTDOT : LINE_DASHDOTDOT_ZERO; break;
			case SWT.LINE_CUSTOM: dashes = data.lineDashes; break;
		}
		if (dashes != null) {
			double[] lengths = new double[dashes.length];
			for (int i = 0; i < lengths.length; i++) {
				lengths[i] = width == 0 || data.lineStyle == SWT.LINE_CUSTOM ? dashes[i] : dashes[i] * width;
			}
			path.setLineDash(lengths, lengths.length, data.lineDashesOffset);
		} else {
			path.setLineDash(null, 0, 0);
		}
	}
	if ((state & LINE_MITERLIMIT) != 0) {
		path.setMiterLimit(data.lineMiterLimit);
	}
	if ((state & LINE_JOIN) != 0) {
		int joinStyle = 0;
		switch (data.lineJoin) {
			case SWT.JOIN_MITER: joinStyle = OS.NSMiterLineJoinStyle; break;
			case SWT.JOIN_ROUND: joinStyle = OS.NSRoundLineJoinStyle; break;
			case SWT.JOIN_BEVEL: joinStyle = OS.NSBevelLineJoinStyle; break;
		}
		path.setLineJoinStyle(joinStyle);
	}
	if ((state & LINE_CAP) != 0) {
		int capStyle = 0;
		switch (data.lineCap) {
			case SWT.CAP_ROUND: capStyle = OS.NSRoundLineCapStyle; break;
			case SWT.CAP_FLAT: capStyle = OS.NSButtLineCapStyle; break;
			case SWT.CAP_SQUARE: capStyle = OS.NSSquareLineCapStyle; break;
		}
		path.setLineCapStyle(capStyle);
	}
	if ((state & DRAW_OFFSET) != 0) {
		data.drawXOffset = data.drawYOffset = 0;
		NSSize size = new NSSize();
		size.width = size.height = 1;
		if (data.transform != null) {
			size = data.transform.transformSize(size);
		}
		double scaling = size.width;
		if (scaling < 0) scaling = -scaling;
		double strokeWidth = data.lineWidth * scaling;
		if (strokeWidth == 0 || ((int)strokeWidth % 2) == 1) {
			data.drawXOffset = 0.5f / scaling;
		}
		scaling = size.height;
		if (scaling < 0) scaling = -scaling;
		strokeWidth = data.lineWidth * scaling;
		if (strokeWidth == 0 || ((int)strokeWidth % 2) == 1) {
			data.drawYOffset = 0.5f / scaling;
		}
	}
	return pool;
}

/**
 * Copies a rectangular area of the receiver at the specified
 * position into the image, which must be of type <code>SWT.BITMAP</code>.
 *
 * @param image the image to copy into
 * @param x the x coordinate in the receiver of the area to be copied
 * @param y the y coordinate in the receiver of the area to be copied
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the image is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the image is not a bitmap or has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void copyArea(Image image, int x, int y) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (image.type != SWT.BITMAP || image.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	NSAutoreleasePool pool = checkGC(TRANSFORM | CLIPPING);
	try {
		if (data.image != null) {
			int srcX = x, srcY = y, destX = 0, destY = 0;
			int scaleFactor = DPIUtil.getDeviceZoom () / 100;
			NSSize srcSize = data.image.handle.size();
			int imgHeight = (int)srcSize.height;
			int destWidth = (int)srcSize.width - x, destHeight = (int)srcSize.height - y;
			int srcWidth = destWidth, srcHeight = destHeight;
			NSGraphicsContext context = NSGraphicsContext.graphicsContextWithBitmapImageRep(image.getRepresentation());
			NSGraphicsContext.static_saveGraphicsState();
			NSGraphicsContext.setCurrentContext(context);
			NSAffineTransform transform = NSAffineTransform.transform();
			NSSize size = image.handle.size();
			transform.translateXBy(0, size.height-(destHeight + 2 * destY));
			transform.concat();
			NSRect srcRect = new NSRect();
			srcRect.x = srcX;
			srcRect.y = imgHeight - (srcY + srcHeight);
			srcRect.width = srcWidth;
			srcRect.height = srcHeight;
			NSRect destRect = new NSRect();
			destRect.x = destX;
			destRect.y = destY;
			destRect.width = destWidth * scaleFactor;
			destRect.height = destHeight * scaleFactor;
			data.image.handle.drawInRect(destRect, srcRect, OS.NSCompositeCopy, 1);
			NSGraphicsContext.static_restoreGraphicsState();
			return;
		}
		if (data.view != null) {
			NSSize size = image.handle.size();
			NSView topView = getTopView(data.view);
			NSRect rect = new NSRect();
			rect.x = x;
			rect.y = y;
			rect.width = size.width;
			rect.height = size.height;
			NSBitmapImageRep imageRep = topView.bitmapImageRepForCachingDisplayInRect(rect);
			imageRep.setSize(size);
			/*
			 * NSView.cacheDisplayInRect will cause an unexpected SWT.Paint event to be sent.
			 * This is handled by Control.cacheDisplayInRect_toBitmapImageRep().
			 */
			topView.cacheDisplayInRect(rect, imageRep);
			NSBitmapImageRep rep = image.getRepresentation();
			image.handle.addRepresentation(imageRep);
			image.handle.removeRepresentation(rep);
			return;
		}
		if (handle.isDrawingToScreen()) {
			NSImage imageHandle = image.handle;
			NSSize size = imageHandle.size();
			NSArray screens = null;
			NSString key = null;
			screens = NSScreen.screens();
			key = NSString.stringWith("NSScreenNumber");
			CGRect rect = new CGRect();
			rect.origin.x = x;
			rect.origin.y = y;
			rect.size.width = size.width;
			rect.size.height = size.height;
			int displayCount = 16;
			long displays = C.malloc(4 * displayCount), countPtr = C.malloc(4);
			if (OS.CGGetDisplaysWithRect(rect, displayCount, displays, countPtr) != 0) return;
			int[] count = new int[1], display = new int[1];
			C.memmove(count, countPtr, C.PTR_SIZEOF);
			for (int i = 0; i < count[0]; i++) {
				C.memmove(display, displays + (i * 4), 4);
				OS.CGDisplayBounds(display[0], rect);
				double scaling = 1;
				if (screens != null) {
					for (int j = 0; j < screens.count(); j++) {
						NSScreen screen = new NSScreen(screens.objectAtIndex(j));
						if (display[0] == new NSNumber(screen.deviceDescription().objectForKey(key)).intValue()) {
							scaling = screen.backingScaleFactor();
							break;
						}
					}
				}
				/*
				 * Add a high resolution image representation to the image if scaling factor is > 1
				 */
				if (scaling > 1) {
					int width = (int) (size.width * scaling);
					int height = (int) (size.height * scaling);
					NSBitmapImageRep rep = (NSBitmapImageRep)new NSBitmapImageRep().alloc();
					rep = rep.initWithBitmapDataPlanes(0, width, height, 8, 3, false, false, OS.NSDeviceRGBColorSpace, OS.NSAlphaFirstBitmapFormat | OS.NSAlphaNonpremultipliedBitmapFormat, width * 4, 32);
					C.memset(rep.bitmapData(), 0xFF, width * height * 4);
					imageHandle.addRepresentation(rep);
					rep.release();
				}
				long srcImage = 0;
				srcImage = OS.CGDisplayCreateImage(display[0]);
				if (srcImage != 0) {
					copyArea(image, (int)(x * scaling - rect.origin.x), (int)(y * scaling - rect.origin.y), srcImage);
					OS.CGImageRelease(srcImage);
				}
			}
			C.free(displays);
			C.free(countPtr);
		}
	} finally {
		uncheckGC(pool);
	}
}

void copyArea (Image image, int x, int y, long srcImage) {
	if (srcImage == 0) return;
	NSBitmapImageRep rep = image.getRepresentation();
	long bpc = rep.bitsPerSample();
	long width = rep.pixelsWide();
	long height = rep.pixelsHigh();
	long bpr = rep.bytesPerRow();
	long data = rep.bitmapData();
	long format = rep.bitmapFormat();
	int alphaInfo;
	if (rep.hasAlpha()) {
		alphaInfo = (format & OS.NSAlphaFirstBitmapFormat) != 0 ? OS.kCGImageAlphaFirst : OS.kCGImageAlphaLast;
	} else {
		alphaInfo = (format & OS.NSAlphaFirstBitmapFormat) != 0 ? OS.kCGImageAlphaNoneSkipFirst : OS.kCGImageAlphaNoneSkipLast;
	}
	long colorspace = OS.CGColorSpaceCreateDeviceRGB();
	long context = OS.CGBitmapContextCreate(data, width, height, bpc, bpr, colorspace, alphaInfo);
	OS.CGColorSpaceRelease(colorspace);
	if (context != 0) {
		CGRect rect = new CGRect();
		rect.origin.x = -x;
		rect.origin.y = y;
		rect.size.width = OS.CGImageGetWidth(srcImage);
		rect.size.height = OS.CGImageGetHeight(srcImage);
		OS.CGContextTranslateCTM(context, 0, -(rect.size.height - height));
		OS.CGContextDrawImage(context, rect, srcImage);
		OS.CGContextRelease(context);
	}
}

/**
 * Copies a rectangular area of the receiver at the source
 * position onto the receiver at the destination position.
 *
 * @param srcX the x coordinate in the receiver of the area to be copied
 * @param srcY the y coordinate in the receiver of the area to be copied
 * @param width the width of the area to copy
 * @param height the height of the area to copy
 * @param destX the x coordinate in the receiver of the area to copy to
 * @param destY the y coordinate in the receiver of the area to copy to
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void copyArea(int srcX, int srcY, int width, int height, int destX, int destY) {
	copyArea(srcX, srcY, width, height, destX, destY, true);
}
/**
 * Copies a rectangular area of the receiver at the source
 * position onto the receiver at the destination position.
 *
 * @param srcX the x coordinate in the receiver of the area to be copied
 * @param srcY the y coordinate in the receiver of the area to be copied
 * @param width the width of the area to copy
 * @param height the height of the area to copy
 * @param destX the x coordinate in the receiver of the area to copy to
 * @param destY the y coordinate in the receiver of the area to copy to
 * @param paint if <code>true</code> paint events will be generated for old and obscured areas
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @since 3.1
 */
public void copyArea(int srcX, int srcY, int width, int height, int destX, int destY, boolean paint) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (width <= 0 || height <= 0) return;
	int deltaX = destX - srcX, deltaY = destY - srcY;
	if (deltaX == 0 && deltaY == 0) return;
	NSAutoreleasePool pool = checkGC(TRANSFORM | CLIPPING);
	try {
		Image image = data.image;
		if (image != null) {
			NSImage imageHandle = image.handle;
			NSSize size = imageHandle.size();
			int imgHeight = (int)size.height;
			handle.saveGraphicsState();
			NSAffineTransform transform = NSAffineTransform.transform();
			transform.scaleXBy(1, -1);
			transform.translateXBy(0, -(height + 2 * destY));
			transform.concat();
			NSRect srcRect = new NSRect();
			srcRect.x = srcX;
			srcRect.y = imgHeight - (srcY + height);
			srcRect.width = width;
			srcRect.height = height;
			NSRect destRect = new NSRect();
			destRect.x = destX;
			destRect.y = destY;
			destRect.width = width;
			destRect.height = height;
			imageHandle.drawInRect(destRect, srcRect, OS.NSCompositeCopy, 1);
			handle.restoreGraphicsState();
			return;
		}
		if (data.view != null) {
			NSView view = data.view;
			NSRect visibleRect = view.visibleRect();
			if (visibleRect.width <= 0 || visibleRect.height <= 0) return;
			NSRect damage = new NSRect();
			damage.x = srcX;
			damage.y = srcY;
			damage.width = width;
			damage.height = height;
			NSPoint dest = new NSPoint();
			dest.x = destX;
			dest.y = destY;

			view.lockFocus();
			NSSize delta = new NSSize();
			delta.width = deltaX;
			delta.height = deltaY;
			view.scrollRect(damage, delta);
			view.unlockFocus();

			if (paint) {
				boolean disjoint = (destX + width < srcX) || (srcX + width < destX) || (destY + height < srcY) || (srcY + height < destY);
				if (disjoint) {
					view.setNeedsDisplayInRect(damage);
				} else {
					if (deltaX != 0) {
						int newX = destX - deltaX;
						if (deltaX < 0) newX = destX + width;
						damage.x = newX;
						damage.width = Math.abs(deltaX);
						view.setNeedsDisplayInRect(damage);
					}
					if (deltaY != 0) {
						int newY = destY - deltaY;
						if (deltaY < 0) newY = destY + height;
						damage.x = srcX;
						damage.y = newY;
						damage.width = width;
						damage.height =  Math.abs (deltaY);
						view.setNeedsDisplayInRect(damage);
					}
				}

				NSRect srcRect = new NSRect();
				srcRect.x = srcX;
				srcRect.y = srcY;
				srcRect.width = width;
				srcRect.height = height;
				OS.NSIntersectionRect(visibleRect, visibleRect, srcRect);

				if (!OS.NSEqualRects(visibleRect, srcRect)) {
					if (srcRect.x != visibleRect.x) {
						damage.x = srcRect.x + deltaX;
						damage.y = srcRect.y + deltaY;
						damage.width = visibleRect.x - srcRect.x;
						damage.height = srcRect.height;
						view.setNeedsDisplayInRect(damage);
					}
					if (visibleRect.x + visibleRect.width != srcRect.x + srcRect.width) {
						damage.x = srcRect.x + visibleRect.width + deltaX;
						damage.y = srcRect.y + deltaY;
						damage.width = srcRect.width - visibleRect.width;
						damage.height = srcRect.height;
						view.setNeedsDisplayInRect(damage);
					}
					if (visibleRect.y != srcRect.y) {
						damage.x = visibleRect.x + deltaX;
						damage.y = srcRect.y + deltaY;
						damage.width = visibleRect.width;
						damage.height = visibleRect.y - srcRect.y;
						view.setNeedsDisplayInRect(damage);
					}
					if (visibleRect.y + visibleRect.height != srcRect.y + srcRect.height) {
						damage.x = visibleRect.x + deltaX;
						damage.y = visibleRect.y + visibleRect.height + deltaY;
						damage.width = visibleRect.width;
						damage.height = srcRect.y + srcRect.height - (visibleRect.y + visibleRect.height);
						view.setNeedsDisplayInRect(damage);
					}
				}
			}
			return;
		}
	} finally {
		uncheckGC(pool);
	}
}

static long createCGPathRef(NSBezierPath nsPath) {
	long count = nsPath.elementCount();
	if (count > 0) {
		long cgPath = OS.CGPathCreateMutable();
		if (cgPath == 0) SWT.error(SWT.ERROR_NO_HANDLES);
		long points = C.malloc(NSPoint.sizeof * 3);
		if (points == 0) SWT.error(SWT.ERROR_NO_HANDLES);
		double [] pt = new double [6];
		for (int i = 0; i < count; i++) {
			int element = (int)nsPath.elementAtIndex(i, points);
			switch (element) {
				case OS.NSMoveToBezierPathElement:
					C.memmove(pt, points, NSPoint.sizeof);
					OS.CGPathMoveToPoint(cgPath, 0, pt[0], pt[1]);
					break;
				case OS.NSLineToBezierPathElement:
					C.memmove(pt, points, NSPoint.sizeof);
					OS.CGPathAddLineToPoint(cgPath, 0, pt[0], pt[1]);
					break;
				case OS.NSCurveToBezierPathElement:
					C.memmove(pt, points, NSPoint.sizeof * 3);
					OS.CGPathAddCurveToPoint(cgPath, 0, pt[0], pt[1], pt[2], pt[3], pt[4], pt[5]);
					break;
				case OS.NSClosePathBezierPathElement:
					OS.CGPathCloseSubpath(cgPath);
					break;
			}
		}
		C.free(points);
		return cgPath;
	}
	return 0;
}

void createLayout () {
	NSSize size = new NSSize();
	size.width = OS.MAX_TEXT_CONTAINER_SIZE;
	size.height = OS.MAX_TEXT_CONTAINER_SIZE;
	NSTextStorage textStorage = (NSTextStorage)new NSTextStorage().alloc().init();
	NSLayoutManager layoutManager = (NSLayoutManager)new NSLayoutManager().alloc().init();
	layoutManager.setBackgroundLayoutEnabled(NSThread.isMainThread());
	NSTextContainer textContainer = (NSTextContainer)new NSTextContainer().alloc();
	textContainer = textContainer.initWithContainerSize(size);
	textContainer.setLineFragmentPadding(0);
	textStorage.addLayoutManager(layoutManager);
	layoutManager.addTextContainer(textContainer);
	layoutManager.release();
	textContainer.release();
	data.textContainer = textContainer;
	data.layoutManager = layoutManager;
	data.textStorage = textStorage;
}

NSAttributedString createString(String string, int flags, boolean draw) {
	NSMutableDictionary dict = ((NSMutableDictionary)new NSMutableDictionary().alloc()).initWithCapacity(5);
	Font font = data.font;
	dict.setObject(font.handle, OS.NSFontAttributeName);
	font.addTraits(dict);
	if (draw) {
		Pattern pattern = data.foregroundPattern;
		if (pattern != null) {
			if (pattern.color != null) dict.setObject(pattern.color, OS.NSForegroundColorAttributeName);
		} else {
			NSColor fg = data.fg;
			if (fg == null) {
				double [] color = data.foreground;
				fg = data.fg = NSColor.colorWithDeviceRed(color[0], color[1], color[2], data.alpha / 255f);
				fg.retain();
			}
			dict.setObject(fg, OS.NSForegroundColorAttributeName);
		}
	}
	if ((flags & SWT.DRAW_TAB) == 0) {
		dict.setObject(device.paragraphStyle, OS.NSParagraphStyleAttributeName);
	}
	int length = string.length();
	char[] chars = new char[length];
	string.getChars(0, length, chars, 0);
	if ((flags & SWT.DRAW_MNEMONIC) !=0 || (flags & SWT.DRAW_DELIMITER) == 0) {
		int i=0, j=0;
		while (i < chars.length) {
			char c = chars [j++] = chars [i++];
			switch (c) {
				case '&': {
					if ((flags & SWT.DRAW_MNEMONIC) != 0) {
						if (i == chars.length) {continue;}
						if (chars [i] == '&') {i++; continue;}
						j--;
					}
					break;
				}
				case '\r':
				case '\n': {
					if ((flags & SWT.DRAW_DELIMITER) == 0) {
						if (c == '\r' && i != chars.length && chars[i] == '\n') i++;
						j--;
					}
					break;
				}
			}
		}
		length = j;
	}
	NSString str = ((NSString)new NSString().alloc()).initWithCharacters(chars, length);
	NSAttributedString attribStr = ((NSAttributedString)new NSAttributedString().alloc()).initWithString(str, dict);
	dict.release();
	str.release();
	return attribStr;
}

NSBezierPath createNSBezierPath (long  cgPath) {
	Callback callback = new Callback(this, "applierFunc", 2);
	long  proc = callback.getAddress();
	count = typeCount = 0;
	element = new CGPathElement();
	OS.CGPathApply(cgPath, 0, proc);
	types = new byte[typeCount];
	points = new double [count];
	point = new double [6];
	count = typeCount = 0;
	OS.CGPathApply(cgPath, 0, proc);
	callback.dispose();

	NSBezierPath bezierPath = NSBezierPath.bezierPath();
	NSPoint nsPoint = new NSPoint(), nsPoint2 = new NSPoint(), nsPoint3 = new NSPoint();
	for (int i = 0, j = 0; i < types.length; i++) {
		switch (types[i]) {
			case SWT.PATH_MOVE_TO:
				nsPoint.x = points[j++];
				nsPoint.y = points[j++];
				bezierPath.moveToPoint(nsPoint);
				break;
			case SWT.PATH_LINE_TO:
				nsPoint.x = points[j++];
				nsPoint.y = points[j++];
				bezierPath.lineToPoint(nsPoint);
				break;
			case SWT.PATH_CUBIC_TO:
				nsPoint2.x = points[j++];
				nsPoint2.y = points[j++];
				nsPoint3.x = points[j++];
				nsPoint3.y = points[j++];
				nsPoint.x = points[j++];
				nsPoint.y = points[j++];
				bezierPath.curveToPoint(nsPoint, nsPoint2, nsPoint3);
				break;
			case SWT.PATH_QUAD_TO:
				double currentX = nsPoint.x;
				double currentY = nsPoint.y;
				nsPoint2.x = points[j++];
				nsPoint2.y = points[j++];
				nsPoint.x = points[j++];
				nsPoint.y = points[j++];
				double x0 = currentX;
				double y0 = currentY;
				double cx1 = x0 + 2 * (nsPoint2.x - x0) / 3;
				double cy1 = y0 + 2 * (nsPoint2.y - y0) / 3;
				double cx2 = cx1 + (nsPoint.x - x0) / 3;
				double cy2 = cy1 + (nsPoint.y - y0) / 3;
				nsPoint2.x = cx1;
				nsPoint2.y = cy1;
				nsPoint3.x = cx2;
				nsPoint3.y = cy2;
				bezierPath.curveToPoint(nsPoint, nsPoint2, nsPoint3);
				break;
			case SWT.PATH_CLOSE:
				bezierPath.closePath();
				break;
			default:
				dispose();
				SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		}
	}
	element = null;
	types = null;
	points = null;
	nsPoint = null;
	return bezierPath;
}

@Override
void destroy() {
	/* Free resources */
	Image image = data.image;
	if (image != null) {
		image.memGC = null;
		image.createAlpha();
	}
	if (data.textStorage != null) data.textStorage.release();
	data.textStorage = null;
	data.layoutManager = null;
	data.textContainer = null;
	if (data.fg != null) data.fg.release();
	if (data.bg != null) data.bg.release();
	if (data.path != null) data.path.release();
	if (data.clipPath != null) data.clipPath.release();
	if (data.visiblePath != null) data.visiblePath.release();
	if (data.transform != null) data.transform.release();
	if (data.inverseTransform != null) data.inverseTransform.release();
	data.path = data.clipPath = data.visiblePath = null;
	data.transform = data.inverseTransform = null;
	data.fg = data.bg = null;
	textDataCache.release();

	/* Dispose the GC */
	if (drawable != null) drawable.internal_dispose_GC(handle.id, data);
	handle.restoreGraphicsState();
	handle.release();

	drawable = null;
	data.image = null;
	data = null;
	handle = null;
}

/**
 * Draws the outline of a circular or elliptical arc
 * within the specified rectangular area.
 * <p>
 * The resulting arc begins at <code>startAngle</code> and extends
 * for <code>arcAngle</code> degrees, using the current color.
 * Angles are interpreted such that 0 degrees is at the 3 o'clock
 * position. A positive value indicates a counter-clockwise rotation
 * while a negative value indicates a clockwise rotation.
 * </p><p>
 * The center of the arc is the center of the rectangle whose origin
 * is (<code>x</code>, <code>y</code>) and whose size is specified by the
 * <code>width</code> and <code>height</code> arguments.
 * </p><p>
 * The resulting arc covers an area <code>width + 1</code> points wide
 * by <code>height + 1</code> points tall.
 * </p>
 *
 * @param x the x coordinate of the upper-left corner of the arc to be drawn
 * @param y the y coordinate of the upper-left corner of the arc to be drawn
 * @param width the width of the arc to be drawn
 * @param height the height of the arc to be drawn
 * @param startAngle the beginning angle
 * @param arcAngle the angular extent of the arc, relative to the start angle
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (width < 0) {
		x = x + width;
		width = -width;
	}
	if (height < 0) {
		y = y + height;
		height = -height;
	}
	if (width == 0 || height == 0 || arcAngle == 0) return;
	NSAutoreleasePool pool = checkGC(DRAW);
	try {
		handle.saveGraphicsState();
		NSAffineTransform transform = NSAffineTransform.transform();
		double xOffset = data.drawXOffset, yOffset = data.drawYOffset;
		transform.translateXBy(x + xOffset + width / 2f, y + yOffset + height / 2f);
		transform.scaleXBy(width / 2f, height / 2f);
		NSBezierPath path = data.path;
		NSPoint center = new NSPoint();
		float sAngle = -startAngle;
		float eAngle = -(startAngle + arcAngle);
		path.appendBezierPathWithArcWithCenter(center, 1, sAngle,  eAngle, arcAngle>0);
		path.transformUsingAffineTransform(transform);
		Pattern pattern = data.foregroundPattern;
		if (pattern != null) setPatternPhase(pattern);
		if (pattern != null && pattern.gradient != null) {
			strokePattern(path, pattern);
		} else {
			path.stroke();
		}
		path.removeAllPoints();
		handle.restoreGraphicsState();
	} finally {
		uncheckGC(pool);
	}
}

/**
 * Draws a rectangle, based on the specified arguments, which has
 * the appearance of the platform's <em>focus rectangle</em> if the
 * platform supports such a notion, and otherwise draws a simple
 * rectangle in the receiver's foreground color.
 *
 * @param x the x coordinate of the rectangle
 * @param y the y coordinate of the rectangle
 * @param width the width of the rectangle
 * @param height the height of the rectangle
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #drawRectangle(int, int, int, int)
 */
public void drawFocus(int x, int y, int width, int height) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	NSAutoreleasePool pool = checkGC(CLIPPING | TRANSFORM);
	try {
		int[] metric = new int[1];
		OS.GetThemeMetric(OS.kThemeMetricFocusRectOutset, metric);
		CGRect rect = new CGRect();
		rect.origin.x = x + metric[0];
		rect.origin.y = y + metric[0];
		rect.size.width = width - metric[0] * 2;
		rect.size.height = height - metric[0] * 2;
		OS.HIThemeDrawFocusRect(rect, true, handle.graphicsPort(), OS.kHIThemeOrientationNormal);
	} finally {
		uncheckGC(pool);
	}
}

/**
 * Draws the given image in the receiver at the specified
 * coordinates.
 *
 * @param image the image to draw
 * @param x the x coordinate of where to draw
 * @param y the y coordinate of where to draw
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the image is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the given coordinates are outside the bounds of the image</li></ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 * @exception SWTError <ul>
 *    <li>ERROR_NO_HANDLES - if no handles are available to perform the operation</li>
 * </ul>
 */
public void drawImage(Image image, int x, int y) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (image.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	drawImage(image, 0, 0, -1, -1, x, y, -1, -1, true);
}

/**
 * Copies a rectangular area from the source image into a (potentially
 * different sized) rectangular area in the receiver. If the source
 * and destination areas are of differing sizes, then the source
 * area will be stretched or shrunk to fit the destination area
 * as it is copied. The copy fails if any part of the source rectangle
 * lies outside the bounds of the source image, or if any of the width
 * or height arguments are negative.
 *
 * @param image the source image
 * @param srcX the x coordinate in the source image to copy from
 * @param srcY the y coordinate in the source image to copy from
 * @param srcWidth the width in points to copy from the source
 * @param srcHeight the height in points to copy from the source
 * @param destX the x coordinate in the destination to copy to
 * @param destY the y coordinate in the destination to copy to
 * @param destWidth the width in points of the destination rectangle
 * @param destHeight the height in points of the destination rectangle
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the image is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
 *    <li>ERROR_INVALID_ARGUMENT - if any of the width or height arguments are negative.
 *    <li>ERROR_INVALID_ARGUMENT - if the source rectangle is not contained within the bounds of the source image</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 * @exception SWTError <ul>
 *    <li>ERROR_NO_HANDLES - if no handles are available to perform the operation</li>
 * </ul>
 */
public void drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (srcWidth == 0 || srcHeight == 0 || destWidth == 0 || destHeight == 0) return;
	if (srcX < 0 || srcY < 0 || srcWidth < 0 || srcHeight < 0 || destWidth < 0 || destHeight < 0) {
		SWT.error (SWT.ERROR_INVALID_ARGUMENT);
	}
	if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (image.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	drawImage(image, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, false);
}

void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple) {
	NSImage imageHandle = srcImage.handle;
	NSSize size = imageHandle.size();
	int imgWidth = (int)size.width;
	int imgHeight = (int)size.height;
	if (simple) {
		srcWidth = destWidth = imgWidth;
		srcHeight = destHeight = imgHeight;
	} else {
		simple = srcX == 0 && srcY == 0 &&
			srcWidth == destWidth && destWidth == imgWidth &&
			srcHeight == destHeight && destHeight == imgHeight;
		if (srcX + srcWidth > imgWidth || srcY + srcHeight > imgHeight) {
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		}
	}
	NSAutoreleasePool pool = checkGC(CLIPPING | TRANSFORM);
	try {
		if (srcImage.memGC != null) {
			srcImage.createAlpha();
		}
		handle.saveGraphicsState();
		NSAffineTransform transform = NSAffineTransform.transform();
		transform.scaleXBy(1, -1);
		transform.translateXBy(0, -(destHeight + 2 * destY));
		transform.concat();
		NSRect srcRect = new NSRect();
		srcRect.x = srcX;
		srcRect.y = imgHeight - (srcY + srcHeight);
		srcRect.width = srcWidth;
		srcRect.height = srcHeight;
		NSRect destRect = new NSRect();
		destRect.x = destX;
		destRect.y = destY;
		destRect.width = destWidth;
		destRect.height = destHeight;
		imageHandle.drawInRect(destRect, srcRect, OS.NSCompositeSourceOver, data.alpha / 255f);
		handle.restoreGraphicsState();
	} finally {
		uncheckGC(pool);
	}
}

/**
 * Draws a line, using the foreground color, between the points
 * (<code>x1</code>, <code>y1</code>) and (<code>x2</code>, <code>y2</code>).
 *
 * @param x1 the first point's x coordinate
 * @param y1 the first point's y coordinate
 * @param x2 the second point's x coordinate
 * @param y2 the second point's y coordinate
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void drawLine(int x1, int y1, int x2, int y2) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (x1 == x2 && y1 == y2 && data.lineWidth <= 1) {
		drawPoint(x1, y1);
		return;
	}
	NSAutoreleasePool pool = checkGC(DRAW);
	try {
		NSBezierPath path = data.path;
		NSPoint pt = new NSPoint();
		pt.x = x1 + data.drawXOffset;
		pt.y = y1 + data.drawYOffset;
		path.moveToPoint(pt);
		pt.x = x2 + data.drawXOffset;
		pt.y = y2 + data.drawYOffset;
		path.lineToPoint(pt);
		Pattern pattern = data.foregroundPattern;
		if (pattern != null) setPatternPhase(pattern);
		if (pattern != null && pattern.gradient != null) {
			strokePattern(path, pattern);
		} else {
			path.stroke();
		}
		path.removeAllPoints();
	} finally {
		uncheckGC(pool);
	}
}

/**
 * Draws the outline of an oval, using the foreground color,
 * within the specified rectangular area.
 * <p>
 * The result is a circle or ellipse that fits within the
 * rectangle specified by the <code>x</code>, <code>y</code>,
 * <code>width</code>, and <code>height</code> arguments.
 * </p><p>
 * The oval covers an area that is <code>width + 1</code>
 * points wide and <code>height + 1</code> points tall.
 * </p>
 *
 * @param x the x coordinate of the upper left corner of the oval to be drawn
 * @param y the y coordinate of the upper left corner of the oval to be drawn
 * @param width the width of the oval to be drawn
 * @param height the height of the oval to be drawn
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void drawOval(int x, int y, int width, int height) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	NSAutoreleasePool pool = checkGC(DRAW);
	try {
		if (width < 0) {
			x = x + width;
			width = -width;
		}
		if (height < 0) {
			y = y + height;
			height = -height;
		}
		NSBezierPath path = data.path;
		NSRect rect = new NSRect();
		rect.x = x + data.drawXOffset;
		rect.y = y + data.drawXOffset;
		rect.width = width;
		rect.height = height;
		path.appendBezierPathWithOvalInRect(rect);
		Pattern pattern = data.foregroundPattern;
		if (pattern != null) setPatternPhase(pattern);
		if (pattern != null && pattern.gradient != null) {
			strokePattern(path, pattern);
		} else {
			path.stroke();
		}
		path.removeAllPoints();
	} finally {
		uncheckGC(pool);
	}
}

/**
 * Draws the path described by the parameter.
 * <p>
 * This operation requires the operating system's advanced
 * graphics subsystem which may not be available on some
 * platforms.
 * </p>
 *
 * @param path the path to draw
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the parameter is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the parameter has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li>
 * </ul>
 *
 * @see Path
 *
 * @since 3.1
 */
public void drawPath(Path path) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (path == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (path.handle == null) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	NSAutoreleasePool pool = checkGC(DRAW);
	try {
		handle.saveGraphicsState();
		NSAffineTransform transform = NSAffineTransform.transform();
		transform.translateXBy(data.drawXOffset, data.drawYOffset);
		transform.concat();
		NSBezierPath drawPath = data.path;
		drawPath.appendBezierPath(path.handle);
		Pattern pattern = data.foregroundPattern;
		if (pattern != null) setPatternPhase(pattern);
		if (pattern != null && pattern.gradient != null) {
			strokePattern(drawPath, pattern);
		} else {
			drawPath.stroke();
		}
		drawPath.removeAllPoints();
		handle.restoreGraphicsState();
	} finally {
		uncheckGC(pool);
	}
}

/**
 * Draws an SWT logical point, using the foreground color, at the specified
 * point (<code>x</code>, <code>y</code>).
 * <p>
 * Note that the receiver's line attributes do not affect this
 * operation.
 * </p>
 *
 * @param x the point's x coordinate
 * @param y the point's y coordinate
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @since 3.0
 */
public void drawPoint(int x, int y) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	NSAutoreleasePool pool = checkGC(FOREGROUND_FILL | CLIPPING | TRANSFORM);
	try {
		NSRect rect = new NSRect();
		rect.x = x;
		rect.y = y;
		rect.width = 1;
		rect.height = 1;
		NSBezierPath path = data.path;
		path.appendBezierPathWithRect(rect);
		path.fill();
		path.removeAllPoints();
	} finally {
		uncheckGC(pool);
	}
}

/**
 * Draws the closed polygon which is defined by the specified array
 * of integer coordinates, using the receiver's foreground color. The array
 * contains alternating x and y values which are considered to represent
 * points which are the vertices of the polygon. Lines are drawn between
 * each consecutive pair, and between the first pair and last pair in the
 * array.
 *
 * @param pointArray an array of alternating x and y values which are the vertices of the polygon
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT if pointArray is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void drawPolygon(int[] pointArray) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (pointArray == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (pointArray.length < 4) return;
	NSAutoreleasePool pool = checkGC(DRAW);
	try {
		double xOffset = data.drawXOffset, yOffset = data.drawYOffset;
		NSBezierPath path = data.path;
		NSPoint pt = new NSPoint();
		pt.x = pointArray[0] + xOffset;
		pt.y = pointArray[1] + yOffset;
		path.moveToPoint(pt);
		int end = pointArray.length / 2 * 2;
		for (int i = 2; i < end; i+=2) {
			pt.x = pointArray[i] + xOffset;
			pt.y = pointArray[i+1] + yOffset;
			path.lineToPoint(pt);
		}
		path.closePath();
		Pattern pattern = data.foregroundPattern;
		if (pattern != null) setPatternPhase(pattern);
		if (pattern != null && pattern.gradient != null) {
			strokePattern(path, pattern);
		} else {
			path.stroke();
		}
		path.removeAllPoints();
	} finally {
		uncheckGC(pool);
	}
}

/**
 * Draws the polyline which is defined by the specified array
 * of integer coordinates, using the receiver's foreground color. The array
 * contains alternating x and y values which are considered to represent
 * points which are the corners of the polyline. Lines are drawn between
 * each consecutive pair, but not between the first pair and last pair in
 * the array.
 *
 * @param pointArray an array of alternating x and y values which are the corners of the polyline
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the point array is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void drawPolyline(int[] pointArray) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (pointArray == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (pointArray.length < 4) return;
	NSAutoreleasePool pool = checkGC(DRAW);
	try {
		double xOffset = data.drawXOffset, yOffset = data.drawYOffset;
		NSBezierPath path = data.path;
		NSPoint pt = new NSPoint();
		pt.x = pointArray[0] + xOffset;
		pt.y = pointArray[1] + yOffset;
		path.moveToPoint(pt);
		int end = pointArray.length / 2 * 2;
		for (int i = 2; i < end; i+=2) {
			pt.x = pointArray[i] + xOffset;
			pt.y = pointArray[i+1] + yOffset;
			path.lineToPoint(pt);
		}
		Pattern pattern = data.foregroundPattern;
		if (pattern != null) setPatternPhase(pattern);
		if (pattern != null && pattern.gradient != null) {
			strokePattern(path, pattern);
		} else {
			path.stroke();
		}
		path.removeAllPoints();
	} finally {
		uncheckGC(pool);
	}
}

/**
 * Draws the outline of the rectangle specified by the arguments,
 * using the receiver's foreground color. The left and right edges
 * of the rectangle are at <code>x</code> and <code>x + width</code>.
 * The top and bottom edges are at <code>y</code> and <code>y + height</code>.
 *
 * @param x the x coordinate of the rectangle to be drawn
 * @param y the y coordinate of the rectangle to be drawn
 * @param width the width of the rectangle to be drawn
 * @param height the height of the rectangle to be drawn
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void drawRectangle(int x, int y, int width, int height) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	NSAutoreleasePool pool = checkGC(DRAW);
	try {
		if (width < 0) {
			x = x + width;
			width = -width;
		}
		if (height < 0) {
			y = y + height;
			height = -height;
		}
		NSRect rect = new NSRect();
		rect.x = x + data.drawXOffset;
		rect.y = y + data.drawYOffset;
		rect.width = width;
		rect.height = height;
		NSBezierPath path = data.path;
		path.appendBezierPathWithRect(rect);
		Pattern pattern = data.foregroundPattern;
		if (pattern != null) setPatternPhase(pattern);
		if (pattern != null && pattern.gradient != null) {
			strokePattern(path, pattern);
		} else {
			path.stroke();
		}
		path.removeAllPoints();
	} finally {
		uncheckGC(pool);
	}
}

/**
 * Draws the outline of the specified rectangle, using the receiver's
 * foreground color. The left and right edges of the rectangle are at
 * <code>rect.x</code> and <code>rect.x + rect.width</code>. The top
 * and bottom edges are at <code>rect.y</code> and
 * <code>rect.y + rect.height</code>.
 *
 * @param rect the rectangle to draw
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void drawRectangle(Rectangle rect) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (rect == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	drawRectangle (rect.x, rect.y, rect.width, rect.height);
}

/**
 * Draws the outline of the round-cornered rectangle specified by
 * the arguments, using the receiver's foreground color. The left and
 * right edges of the rectangle are at <code>x</code> and <code>x + width</code>.
 * The top and bottom edges are at <code>y</code> and <code>y + height</code>.
 * The <em>roundness</em> of the corners is specified by the
 * <code>arcWidth</code> and <code>arcHeight</code> arguments, which
 * are respectively the width and height of the ellipse used to draw
 * the corners.
 *
 * @param x the x coordinate of the rectangle to be drawn
 * @param y the y coordinate of the rectangle to be drawn
 * @param width the width of the rectangle to be drawn
 * @param height the height of the rectangle to be drawn
 * @param arcWidth the width of the arc
 * @param arcHeight the height of the arc
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void drawRoundRectangle(int x, int y, int width, int height, int arcWidth, int arcHeight) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (arcWidth == 0 || arcHeight == 0) {
		drawRectangle(x, y, width, height);
		return;
	}
	NSAutoreleasePool pool = checkGC(DRAW);
	try {
		NSBezierPath path = data.path;
		NSRect rect = new NSRect();
		rect.x = x + data.drawXOffset;
		rect.y = y + data.drawYOffset;
		rect.width = width;
		rect.height = height;
		path.appendBezierPathWithRoundedRect(rect, arcWidth / 2f, arcHeight / 2f);
		Pattern pattern = data.foregroundPattern;
		if (pattern != null) setPatternPhase(pattern);
		if (pattern != null && pattern.gradient != null) {
			strokePattern(path, pattern);
		} else {
			path.stroke();
		}
		path.removeAllPoints();
	} finally {
		uncheckGC(pool);
	}
}

/**
 * Draws the given string, using the receiver's current font and
 * foreground color. No tab expansion or carriage return processing
 * will be performed. The background of the rectangular area where
 * the string is being drawn will be filled with the receiver's
 * background color.
 * <br><br>
 * On Windows, {@link #drawString} and {@link #drawText} are slightly
 * different, see {@link #drawString(String, int, int, boolean)} for
 * explanation.
 *
 * @param string the string to be drawn
 * @param x the x coordinate of the top left corner of the rectangular area where the string is to be drawn
 * @param y the y coordinate of the top left corner of the rectangular area where the string is to be drawn
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the string is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void drawString (String string, int x, int y) {
	drawString(string, x, y, false);
}

/**
 * Draws the given string, using the receiver's current font and
 * foreground color. No tab expansion or carriage return processing
 * will be performed. If <code>isTransparent</code> is <code>true</code>,
 * then the background of the rectangular area where the string is being
 * drawn will not be modified, otherwise it will be filled with the
 * receiver's background color.
 * <br><br>
 * On Windows, {@link #drawString} and {@link #drawText} are slightly
 * different:
 * <ul>
 *     <li>{@link #drawString} is faster (depends on string size)<br>~7x for 1-char strings<br>~4x for 10-char strings<br>~2x for 100-char strings</li>
 *     <li>{@link #drawString} doesn't try to find a good fallback font when character doesn't have a glyph in currently selected font</li>
 * </ul>
 *
 * @param string the string to be drawn
 * @param x the x coordinate of the top left corner of the rectangular area where the string is to be drawn
 * @param y the y coordinate of the top left corner of the rectangular area where the string is to be drawn
 * @param isTransparent if <code>true</code> the background will be transparent, otherwise it will be opaque
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the string is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void drawString(String string, int x, int y, boolean isTransparent) {
	drawText(string, x, y, isTransparent ? SWT.DRAW_TRANSPARENT : 0);
}

/**
 * Draws the given string, using the receiver's current font and
 * foreground color. Tab expansion and carriage return processing
 * are performed. The background of the rectangular area where
 * the text is being drawn will be filled with the receiver's
 * background color.
 * <br><br>
 * On Windows, {@link #drawString} and {@link #drawText} are slightly
 * different, see {@link #drawString(String, int, int, boolean)} for
 * explanation.
 *
 * @param string the string to be drawn
 * @param x the x coordinate of the top left corner of the rectangular area where the text is to be drawn
 * @param y the y coordinate of the top left corner of the rectangular area where the text is to be drawn
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the string is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void drawText(String string, int x, int y) {
	drawText(string, x, y, SWT.DRAW_DELIMITER | SWT.DRAW_TAB);
}

/**
 * Draws the given string, using the receiver's current font and
 * foreground color. Tab expansion and carriage return processing
 * are performed. If <code>isTransparent</code> is <code>true</code>,
 * then the background of the rectangular area where the text is being
 * drawn will not be modified, otherwise it will be filled with the
 * receiver's background color.
 * <br><br>
 * On Windows, {@link #drawString} and {@link #drawText} are slightly
 * different, see {@link #drawString(String, int, int, boolean)} for
 * explanation.
 *
 * @param string the string to be drawn
 * @param x the x coordinate of the top left corner of the rectangular area where the text is to be drawn
 * @param y the y coordinate of the top left corner of the rectangular area where the text is to be drawn
 * @param isTransparent if <code>true</code> the background will be transparent, otherwise it will be opaque
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the string is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void drawText(String string, int x, int y, boolean isTransparent) {
	int flags = SWT.DRAW_DELIMITER | SWT.DRAW_TAB;
	if (isTransparent) flags |= SWT.DRAW_TRANSPARENT;
	drawText(string, x, y, flags);
}

/**
 * Draws the given string, using the receiver's current font and
 * foreground color. Tab expansion, line delimiter and mnemonic
 * processing are performed according to the specified flags. If
 * <code>flags</code> includes <code>DRAW_TRANSPARENT</code>,
 * then the background of the rectangular area where the text is being
 * drawn will not be modified, otherwise it will be filled with the
 * receiver's background color.
 * <br><br>
 * On Windows, {@link #drawString} and {@link #drawText} are slightly
 * different, see {@link #drawString(String, int, int, boolean)} for
 * explanation.
 *
 * <p>
 * The parameter <code>flags</code> may be a combination of:
 * </p>
 * <dl>
 * <dt><b>DRAW_DELIMITER</b></dt>
 * <dd>draw multiple lines</dd>
 * <dt><b>DRAW_TAB</b></dt>
 * <dd>expand tabs</dd>
 * <dt><b>DRAW_MNEMONIC</b></dt>
 * <dd>underline the mnemonic character</dd>
 * <dt><b>DRAW_TRANSPARENT</b></dt>
 * <dd>transparent background</dd>
 * </dl>
 *
 * @param string the string to be drawn
 * @param x the x coordinate of the top left corner of the rectangular area where the text is to be drawn
 * @param y the y coordinate of the top left corner of the rectangular area where the text is to be drawn
 * @param flags the flags specifying how to process the text
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the string is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void drawText (String string, int x, int y, int flags) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (string == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	NSAutoreleasePool pool = checkGC(CLIPPING | TRANSFORM | FONT | FOREGROUND_FILL);
	try {
		int length = string.length();
		if (length == 0) return;
		boolean mode = true;
		switch (data.textAntialias) {
			case SWT.DEFAULT:
				/* Printer is off by default */
				if (!handle.isDrawingToScreen()) mode = false;
				break;
			case SWT.OFF: mode = false; break;
			case SWT.ON: mode = true; break;
		}
		handle.saveGraphicsState();
		handle.setShouldAntialias(mode);
		if (length == 1 && (flags & SWT.DRAW_TRANSPARENT) != 0) {
			doFastDrawText(string, x, y);
		} else {
			doDrawText(string, x, y, flags);
		}
		handle.restoreGraphicsState();
	} finally {
		uncheckGC(pool);
	}
}

private void doFastDrawText(String string, int x, int y) {
	GCTextData data = getTextData(string);
	data.draw(x, y);
}

private GCTextData getTextData(String string) {
	GCTextData data = (GCTextData) textDataCache.get(string);
	if (data == null) {
		NSAttributedString attribStr = createString(string, 0, true);
		data = new GCTextData(attribStr);
		attribStr.release();
		textDataCache.put(string, data);
	}
	return data;
}

private void doDrawText(String string, int x, int y, int flags) {
	if (data.textStorage == null) createLayout();
	NSAttributedString attribStr = createString(string, flags, true);
	data.textStorage.setAttributedString(attribStr);
	attribStr.release();
	NSPoint pt = new NSPoint();
	pt.x = x;
	pt.y = y;
	NSRange range = data.layoutManager.glyphRangeForTextContainer(data.textContainer);
	if ((flags & SWT.DRAW_TRANSPARENT) == 0) {
		NSRect rect = data.layoutManager.usedRectForTextContainer(data.textContainer);
		rect.x = x;
		rect.y = y;
		Pattern pattern = data.backgroundPattern;
		if (pattern != null) setPatternPhase(pattern);
		if (pattern != null && pattern.gradient != null) {
			NSBezierPath path = NSBezierPath.bezierPathWithRect(rect);
			fillPattern(path, pattern);
		} else {
			NSColor bg = data.bg;
			if (bg == null) {
				double [] color = data.background;
				bg = data.bg = NSColor.colorWithDeviceRed(color[0], color[1], color[2], data.alpha / 255f);
				bg.retain();
			}
			bg.setFill();
			NSBezierPath.fillRect(rect);
		}
	}
	data.layoutManager.drawGlyphsForGlyphRange(range, pt);
}

/**
 * Compares the argument to the receiver, and returns true
 * if they represent the <em>same</em> object using a class
 * specific comparison.
 *
 * @param object the object to compare with this object
 * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise
 *
 * @see #hashCode
 */
@Override
public boolean equals(Object object) {
	if (object == this) return true;
	if (!(object instanceof GC)) return false;
	return handle == ((GC)object).handle;
}

/**
 * Fills the interior of a circular or elliptical arc within
 * the specified rectangular area, with the receiver's background
 * color.
 * <p>
 * The resulting arc begins at <code>startAngle</code> and extends
 * for <code>arcAngle</code> degrees, using the current color.
 * Angles are interpreted such that 0 degrees is at the 3 o'clock
 * position. A positive value indicates a counter-clockwise rotation
 * while a negative value indicates a clockwise rotation.
 * </p><p>
 * The center of the arc is the center of the rectangle whose origin
 * is (<code>x</code>, <code>y</code>) and whose size is specified by the
 * <code>width</code> and <code>height</code> arguments.
 * </p><p>
 * The resulting arc covers an area <code>width + 1</code> points wide
 * by <code>height + 1</code> points tall.
 * </p>
 *
 * @param x the x coordinate of the upper-left corner of the arc to be filled
 * @param y the y coordinate of the upper-left corner of the arc to be filled
 * @param width the width of the arc to be filled
 * @param height the height of the arc to be filled
 * @param startAngle the beginning angle
 * @param arcAngle the angular extent of the arc, relative to the start angle
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #drawArc
 */
public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (width < 0) {
		x = x + width;
		width = -width;
	}
	if (height < 0) {
		y = y + height;
		height = -height;
	}
	if (width == 0 || height == 0 || arcAngle == 0) return;
	NSAutoreleasePool pool = checkGC(FILL);
	try {
		handle.saveGraphicsState();
		NSAffineTransform transform = NSAffineTransform.transform();
		double xOffset = data.drawXOffset, yOffset = data.drawYOffset;
		transform.translateXBy(x + xOffset + width / 2f, y + yOffset + height / 2f);
		transform.scaleXBy(width / 2f, height / 2f);
		NSBezierPath path = data.path;
		NSPoint center = new NSPoint();
		path.moveToPoint(center);
		float sAngle = -startAngle;
		float eAngle = -(startAngle + arcAngle);
		path.appendBezierPathWithArcWithCenter(center, 1, sAngle,  eAngle, arcAngle>0);
		path.closePath();
		path.transformUsingAffineTransform(transform);
		Pattern pattern = data.backgroundPattern;
		if (pattern != null) setPatternPhase(pattern);
		if (pattern != null && pattern.gradient != null) {
			fillPattern(path, pattern);
		} else {
			path.fill();
		}
		path.removeAllPoints();
		handle.restoreGraphicsState();
	} finally {
		uncheckGC(pool);
	}
}

/**
 * Fills the interior of the specified rectangle with a gradient
 * sweeping from left to right or top to bottom progressing
 * from the receiver's foreground color to its background color.
 *
 * @param x the x coordinate of the rectangle to be filled
 * @param y the y coordinate of the rectangle to be filled
 * @param width the width of the rectangle to be filled, may be negative
 *        (inverts direction of gradient if horizontal)
 * @param height the height of the rectangle to be filled, may be negative
 *        (inverts direction of gradient if vertical)
 * @param vertical if true sweeps from top to bottom, else
 *        sweeps from left to right
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #drawRectangle(int, int, int, int)
 */
public void fillGradientRectangle(int x, int y, int width, int height, boolean vertical) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if ((width == 0) || (height == 0)) return;
	NSAutoreleasePool pool = checkGC(CLIPPING | TRANSFORM);
	try {
		RGB backgroundRGB, foregroundRGB;
		backgroundRGB = getBackground().getRGB();
		foregroundRGB = getForeground().getRGB();

		RGB fromRGB, toRGB;
		fromRGB = foregroundRGB;
		toRGB   = backgroundRGB;
		boolean swapColors = false;
		if (width < 0) {
			x += width; width = -width;
			if (! vertical) swapColors = true;
		}
		if (height < 0) {
			y += height; height = -height;
			if (vertical) swapColors = true;
		}
		if (swapColors) {
			fromRGB = backgroundRGB;
			toRGB   = foregroundRGB;
		}
		if (fromRGB.equals(toRGB)) {
			fillRectangle(x, y, width, height);
		} else {
			NSColor startingColor = NSColor.colorWithDeviceRed(fromRGB.red / 255f, fromRGB.green / 255f, fromRGB.blue / 255f, data.alpha / 255f);
			NSColor endingColor = NSColor.colorWithDeviceRed(toRGB.red / 255f, toRGB.green / 255f, toRGB.blue / 255f, data.alpha / 255f);
			NSGradient gradient = ((NSGradient)new NSGradient().alloc()).initWithStartingColor(startingColor, endingColor);
			NSRect rect = new NSRect();
			rect.x = x;
			rect.y = y;
			rect.width = width;
			rect.height = height;
			gradient.drawInRect(rect, vertical ? 90 : 0);
			gradient.release();
		}
	} finally {
		uncheckGC(pool);
	}
}

/**
 * Fills the interior of an oval, within the specified
 * rectangular area, with the receiver's background
 * color.
 *
 * @param x the x coordinate of the upper left corner of the oval to be filled
 * @param y the y coordinate of the upper left corner of the oval to be filled
 * @param width the width of the oval to be filled
 * @param height the height of the oval to be filled
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #drawOval
 */
public void fillOval(int x, int y, int width, int height) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	NSAutoreleasePool pool = checkGC(FILL);
	try {
		if (width < 0) {
			x = x + width;
			width = -width;
		}
		if (height < 0) {
			y = y + height;
			height = -height;
		}
		NSBezierPath path = data.path;
		NSRect rect = new NSRect();
		rect.x = x;
		rect.y = y;
		rect.width = width;
		rect.height = height;
		path.appendBezierPathWithOvalInRect(rect);
		Pattern pattern = data.backgroundPattern;
		if (pattern != null) setPatternPhase(pattern);
		if (pattern != null && pattern.gradient != null) {
			fillPattern(path, pattern);
		} else {
			path.fill();
		}
		path.removeAllPoints();
	} finally {
		uncheckGC(pool);
	}
}

void fillPattern(NSBezierPath path, Pattern pattern) {
	handle.saveGraphicsState();
	path.addClip();
	NSRect bounds = path.bounds();
	NSPoint start = new NSPoint();
	start.x = pattern.pt1.x;
	start.y = pattern.pt1.y;
	NSPoint end = new NSPoint();
	end.x = pattern.pt2.x;
	end.y = pattern.pt2.y;
	double difx = end.x - start.x;
	double dify = end.y - start.y;
	if (difx == 0 && dify == 0) {
		double [] color = pattern.color1;
		NSColor.colorWithDeviceRed(color[0], color[1], color[2], data.alpha / 255f).setFill();
		path.fill();
		handle.restoreGraphicsState();
		return;
	}
	double startx, starty, endx, endy;
	if (difx == 0 || dify == 0) {
		startx = bounds.x;
		starty = bounds.y;
		endx = bounds.x + bounds.width;
		endy = bounds.y + bounds.height;
		if (difx < 0 || dify < 0) {
			startx = endx;
			starty = endy;
			endx = bounds.x;
			endy = bounds.y;
		}
	} else {
		double m = (end.y-start.y)/(end.x - start.x);
		double b = end.y - (m * end.x);
		double m2 = -1/m; //perpendicular slope
		double b2 = bounds.y - (m2 * bounds.x);
		startx = endx = (b - b2) / (m2 - m);
		b2 = (bounds.y + bounds.height) - (m2 * bounds.x);
		double x2 = (b - b2) / (m2 - m);
		startx = difx > 0 ? Math.min(startx, x2) : Math.max(startx, x2);
		endx = difx < 0 ? Math.min(endx, x2) : Math.max(endx, x2);
		b2 = bounds.y - (m2 * (bounds.x + bounds.width));
		x2 = (b - b2) / (m2 - m);
		startx = difx > 0 ? Math.min(startx, x2) : Math.max(startx, x2);
		endx = difx < 0 ? Math.min(endx, x2) : Math.max(endx, x2);
		b2 = (bounds.y + bounds.height) - (m2 * (bounds.x + bounds.width));
		x2 = (b - b2) / (m2 - m);
		startx = difx > 0 ? Math.min(startx, x2) : Math.max(startx, x2);
		endx = difx < 0 ? Math.min(endx, x2) : Math.max(endx, x2);
		starty = (m * startx) + b;
		endy = (m * endx) + b;
	}
	if (difx != 0) {
		while ((difx > 0 && start.x >= startx) || (difx < 0 && start.x <= startx)) {
			start.x -= difx;
			start.y -= dify;
		}
	} else {
		while ((dify > 0 && start.y >= starty) || (dify < 0 && start.y <= starty)) {
			start.x -= difx;
			start.y -= dify;
		}
	}
	end.x = start.x;
	end.y = start.y;
	do {
		end.x += difx;
		end.y += dify;
		pattern.gradient.drawFromPoint(start, end, 0);
		start.x = end.x;
		start.y = end.y;
	} while (
				(difx > 0  && end.x <= endx) ||
				(difx < 0  && end.x >= endx) ||
				(difx == 0 && ((dify > 0  && end.y <= endy) || (dify < 0  && end.y >= endy)))
			);
	handle.restoreGraphicsState();
}

/**
 * Fills the path described by the parameter.
 * <p>
 * This operation requires the operating system's advanced
 * graphics subsystem which may not be available on some
 * platforms.
 * </p>
 *
 * @param path the path to fill
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the parameter is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the parameter has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li>
 * </ul>
 *
 * @see Path
 *
 * @since 3.1
 */
public void fillPath(Path path) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (path == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (path.handle == null) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	NSAutoreleasePool pool = checkGC(FILL);
	try {
		NSBezierPath drawPath = data.path;
		drawPath.appendBezierPath(path.handle);
		Pattern pattern = data.backgroundPattern;
		if (pattern != null) setPatternPhase(pattern);
		if (pattern != null && pattern.gradient != null) {
			fillPattern(drawPath, pattern);
		} else {
			drawPath.fill();
		}
		drawPath.removeAllPoints();
	} finally {
		uncheckGC(pool);
	}
}

/**
 * Fills the interior of the closed polygon which is defined by the
 * specified array of integer coordinates, using the receiver's
 * background color. The array contains alternating x and y values
 * which are considered to represent points which are the vertices of
 * the polygon. Lines are drawn between each consecutive pair, and
 * between the first pair and last pair in the array.
 *
 * @param pointArray an array of alternating x and y values which are the vertices of the polygon
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT if pointArray is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #drawPolygon
 */
public void fillPolygon(int[] pointArray) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (pointArray == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (pointArray.length < 4) return;
	NSAutoreleasePool pool = checkGC(FILL);
	try {
		NSBezierPath path = data.path;
		NSPoint pt = new NSPoint();
		pt.x = pointArray[0];
		pt.y = pointArray[1];
		path.moveToPoint(pt);
		int end = pointArray.length / 2 * 2;
		for (int i = 2; i < end; i+=2) {
			pt.x = pointArray[i];
			pt.y = pointArray[i+1];
			path.lineToPoint(pt);
		}
		path.closePath();
		Pattern pattern = data.backgroundPattern;
		if (pattern != null) setPatternPhase(pattern);
		if (pattern != null && pattern.gradient != null) {
			fillPattern(path, pattern);
		} else {
			path.fill();
		}
		path.removeAllPoints();
	} finally {
		uncheckGC(pool);
	}
}

/**
 * Fills the interior of the rectangle specified by the arguments,
 * using the receiver's background color.
 *
 * @param x the x coordinate of the rectangle to be filled
 * @param y the y coordinate of the rectangle to be filled
 * @param width the width of the rectangle to be filled
 * @param height the height of the rectangle to be filled
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #drawRectangle(int, int, int, int)
 */
public void fillRectangle(int x, int y, int width, int height) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	NSAutoreleasePool pool = checkGC(FILL);
	try {
		if (width < 0) {
			x = x + width;
			width = -width;
		}
		if (height < 0) {
			y = y + height;
			height = -height;
		}
		NSRect rect = new NSRect();
		rect.x = x;
		rect.y = y;
		rect.width = width;
		rect.height = height;
		NSBezierPath path = data.path;
		path.appendBezierPathWithRect(rect);
		Pattern pattern = data.backgroundPattern;
		if (pattern != null) setPatternPhase(pattern);
		if (pattern != null && pattern.gradient != null) {
			fillPattern(path, pattern);
		} else {
			path.fill();
		}
		path.removeAllPoints();
	} finally {
		uncheckGC(pool);
	}
}

/**
 * Fills the interior of the specified rectangle, using the receiver's
 * background color.
 *
 * @param rect the rectangle to be filled
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #drawRectangle(int, int, int, int)
 */
public void fillRectangle(Rectangle rect) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (rect == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	fillRectangle(rect.x, rect.y, rect.width, rect.height);
}

/**
 * Fills the interior of the round-cornered rectangle specified by
 * the arguments, using the receiver's background color.
 *
 * @param x the x coordinate of the rectangle to be filled
 * @param y the y coordinate of the rectangle to be filled
 * @param width the width of the rectangle to be filled
 * @param height the height of the rectangle to be filled
 * @param arcWidth the width of the arc
 * @param arcHeight the height of the arc
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #drawRoundRectangle
 */
public void fillRoundRectangle(int x, int y, int width, int height, int arcWidth, int arcHeight) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (arcWidth == 0 || arcHeight == 0) {
		fillRectangle(x, y, width, height);
		return;
	}
	NSAutoreleasePool pool = checkGC(FILL);
	try {
		NSBezierPath path = data.path;
		NSRect rect = new NSRect();
		rect.x = x;
		rect.y = y;
		rect.width = width;
		rect.height = height;
		path.appendBezierPathWithRoundedRect(rect, arcWidth / 2f, arcHeight / 2f);
		Pattern pattern = data.backgroundPattern;
		if (pattern != null) setPatternPhase(pattern);
		if (pattern != null && pattern.gradient != null) {
			fillPattern(path, pattern);
		} else {
			path.fill();
		}
		path.removeAllPoints();
	} finally {
		uncheckGC(pool);
	}
}

void strokePattern(NSBezierPath path, Pattern pattern) {
	handle.saveGraphicsState();
	long cgPath = createCGPathRef(path);
	long cgContext = handle.graphicsPort();
	OS.CGContextSaveGState(cgContext);
	initCGContext(cgContext);
	OS.CGContextAddPath(cgContext, cgPath);
	OS.CGContextReplacePathWithStrokedPath(cgContext);
	OS.CGPathRelease(cgPath);
	cgPath = 0;
	cgPath = OS.CGContextCopyPath(cgContext);
	if (cgPath == 0) SWT.error(SWT.ERROR_NO_HANDLES);
	OS.CGContextRestoreGState(cgContext);
	NSBezierPath strokePath = createNSBezierPath(cgPath);
	OS.CGPathRelease(cgPath);
	fillPattern(strokePath, pattern);
	handle.restoreGraphicsState();
}

void flush () {
	handle.flushGraphics();
}

/**
 * Returns the <em>advance width</em> of the specified character in
 * the font which is currently selected into the receiver.
 * <p>
 * The advance width is defined as the horizontal distance the cursor
 * should move after printing the character in the selected font.
 * </p>
 *
 * @param ch the character to measure
 * @return the distance in the x direction to move past the character before painting the next
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public int getAdvanceWidth(char ch) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	//NOT DONE
	return stringExtent(new String(new char[]{ch})).x;
}

/**
 * Returns the background color.
 *
 * @return the receiver's background color
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public Color getBackground() {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	return Color.cocoa_new (data.device, data.background);
}

/**
 * Returns the background pattern. The default value is
 * <code>null</code>.
 *
 * @return the receiver's background pattern
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see Pattern
 *
 * @since 3.1
 */
public Pattern getBackgroundPattern() {
	if (handle == null) SWT.error(SWT.ERROR_WIDGET_DISPOSED);
	return data.backgroundPattern;
}

/**
 * Returns <code>true</code> if receiver is using the operating system's
 * advanced graphics subsystem.  Otherwise, <code>false</code> is returned
 * to indicate that normal graphics are in use.
 * <p>
 * Advanced graphics may not be installed for the operating system.  In this
 * case, <code>false</code> is always returned.  Some operating system have
 * only one graphics subsystem.  If this subsystem supports advanced graphics,
 * then <code>true</code> is always returned.  If any graphics operation such
 * as alpha, antialias, patterns, interpolation, paths, clipping or transformation
 * has caused the receiver to switch from regular to advanced graphics mode,
 * <code>true</code> is returned.  If the receiver has been explicitly switched
 * to advanced mode and this mode is supported, <code>true</code> is returned.
 * </p>
 *
 * @return the advanced value
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #setAdvanced
 *
 * @since 3.1
 */
public boolean getAdvanced() {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	return true;
}

/**
 * Returns the receiver's alpha value. The alpha value
 * is between 0 (transparent) and 255 (opaque).
 *
 * @return the alpha value
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @since 3.1
 */
public int getAlpha() {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	return data.alpha;
}

/**
 * Returns the receiver's anti-aliasing setting value, which will be
 * one of <code>SWT.DEFAULT</code>, <code>SWT.OFF</code> or
 * <code>SWT.ON</code>. Note that this controls anti-aliasing for all
 * <em>non-text drawing</em> operations.
 *
 * @return the anti-aliasing setting
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #getTextAntialias
 *
 * @since 3.1
 */
public int getAntialias() {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	return data.antialias;
}

/**
 * Returns the width of the specified character in the font
 * selected into the receiver.
 * <p>
 * The width is defined as the space taken up by the actual
 * character, not including the leading and tailing whitespace
 * or overhang.
 * </p>
 *
 * @param ch the character to measure
 * @return the width of the character
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public int getCharWidth(char ch) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	//NOT DONE
	return stringExtent(new String(new char[]{ch})).x;
}

/**
 * Returns the bounding rectangle of the receiver's clipping
 * region. If no clipping region is set, the return value
 * will be a rectangle which covers the entire bounds of the
 * object the receiver is drawing on.
 *
 * @return the bounding rectangle of the clipping region
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public Rectangle getClipping() {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	NSAutoreleasePool pool = null;
	if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
	try {
		NSRect rect = null;
		if (data.view != null) {
			rect = data.view.visibleRect();
		} else {
			rect = new NSRect();
			if (data.image != null) {
				NSSize size = data.image.handle.size();
				rect.width = size.width;
				rect.height = size.height;
			} else if (data.size != null) {
				rect.width = data.size.width;
				rect.height = data.size.height;
			}
		}
		if (data.paintRect != null || data.clipPath != null || data.inverseTransform != null) {
			if (data.paintRect != null) {
				OS.NSIntersectionRect(rect, rect, data.paintRect);
			}
			if (data.clipPath != null) {
				NSRect clip = data.clipPath.bounds();
				clip.x = (int)clip.x;
				clip.y = (int)clip.y;
				OS.NSIntersectionRect(rect, rect, clip);
			}
			if (data.inverseTransform != null && rect.width > 0 && rect.height > 0) {
				NSPoint pt = new NSPoint();
				pt.x = rect.x;
				pt.y = rect.y;
				NSSize size = new NSSize();
				size.width = rect.width;
				size.height = rect.height;
				pt = data.inverseTransform.transformPoint(pt);
				size =  data.inverseTransform.transformSize(size);
				rect.x = pt.x;
				rect.y = pt.y;
				rect.width = size.width;
				rect.height = size.height;
			}
		}
		return new Rectangle((int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height);
	} finally {
		if (pool != null) pool.release();
	}
}

/**
 * Sets the region managed by the argument to the current
 * clipping region of the receiver.
 *
 * @param region the region to fill with the clipping region
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the region is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the region is disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void getClipping(Region region) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (region == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (region.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	NSAutoreleasePool pool = null;
	if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
	try {
		region.subtract(region);
		NSRect rect = null;
		if (data.view != null) {
			rect = data.view.visibleRect();
		} else {
			rect = new NSRect();
			if (data.image != null) {
				NSSize size = data.image.handle.size();
				rect.width = size.width;
				rect.height = size.height;
			} else if (data.size != null) {
				rect.width = data.size.width;
				rect.height = data.size.height;
			}
		}
		region.add((int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height);
		NSRect paintRect = data.paintRect;
		if (paintRect != null) {
			region.intersect((int)paintRect.x, (int)paintRect.y, (int)paintRect.width, (int)paintRect.height);
		}
		if (data.clipPath != null) {
			NSBezierPath clip = data.clipPath.bezierPathByFlatteningPath();
			int count = (int)clip.elementCount();
			int pointCount = 0;
			Region clipRgn = new Region(device);
			int[] pointArray = new int[count * 2];
			long points = C.malloc(NSPoint.sizeof);
			if (points == 0) SWT.error(SWT.ERROR_NO_HANDLES);
			NSPoint pt = new NSPoint();
			for (int i = 0; i < count; i++) {
				int element = (int)clip.elementAtIndex(i, points);
				switch (element) {
					case OS.NSMoveToBezierPathElement:
						if (pointCount != 0) clipRgn.add(pointArray, pointCount);
						pointCount = 0;
						OS.memmove(pt, points, NSPoint.sizeof);
						pointArray[pointCount++] = (int)pt.x;
						pointArray[pointCount++] = (int)pt.y;
						break;
					case OS.NSLineToBezierPathElement:
						OS.memmove(pt, points, NSPoint.sizeof);
						pointArray[pointCount++] = (int)pt.x;
						pointArray[pointCount++] = (int)pt.y;
						break;
					case OS.NSClosePathBezierPathElement:
						if (pointCount != 0) clipRgn.add(pointArray, pointCount);
						pointCount = 0;
						break;
				}
			}
			if (pointCount != 0) clipRgn.add(pointArray, pointCount);
			C.free(points);
			region.intersect(clipRgn);
			clipRgn.dispose();
		}
		if (data.inverseTransform != null) {
			region.convertRgn(data.inverseTransform);
		}
	} finally {
		if (pool != null) pool.release();
	}
}

/**
 * Returns the receiver's fill rule, which will be one of
 * <code>SWT.FILL_EVEN_ODD</code> or <code>SWT.FILL_WINDING</code>.
 *
 * @return the receiver's fill rule
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @since 3.1
 */
public int getFillRule() {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	return data.fillRule;
}

/**
 * Returns the font currently being used by the receiver
 * to draw and measure text.
 *
 * @return the receiver's font
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public Font getFont() {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	return data.font;
}

/**
 * Returns a FontMetrics which contains information
 * about the font currently being used by the receiver
 * to draw and measure text.
 *
 * @return font metrics for the receiver's font
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public FontMetrics getFontMetrics() {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	NSAutoreleasePool pool = checkGC(FONT);
	try {
		if (data.textStorage == null) createLayout();

		if (data.font.metrics == null) {
			String s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";  //$NON-NLS-1$
			NSMutableDictionary dict = ((NSMutableDictionary)new NSMutableDictionary().alloc()).initWithCapacity(3);
			dict.setObject(data.font.handle, OS.NSFontAttributeName);
			data.font.addTraits(dict);
			NSAttributedString attribStr = ((NSAttributedString)new NSAttributedString().alloc()).initWithString(NSString.stringWith(s), dict);
			data.textStorage.setAttributedString(attribStr);
			attribStr.release();
			dict.release();
			NSLayoutManager layoutManager = data.layoutManager;
			layoutManager.glyphRangeForTextContainer(data.textContainer);
			NSRect rect = layoutManager.usedRectForTextContainer(data.textContainer);
			double avgWidth = Math.ceil(rect.width) / s.length();
			int ascent = (int)layoutManager.defaultBaselineOffsetForFont(data.font.handle);
			int height = (int)layoutManager.defaultLineHeightForFont(data.font.handle);
			data.font.metrics = FontMetrics.cocoa_new(ascent, height - ascent, avgWidth, 0, height);
		}

		return data.font.metrics;
	} finally {
		uncheckGC(pool);
	}
}

/**
 * Returns the receiver's foreground color.
 *
 * @return the color used for drawing foreground things
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public Color getForeground() {
	if (handle == null) SWT.error(SWT.ERROR_WIDGET_DISPOSED);
	return Color.cocoa_new(data.device, data.foreground);
}

/**
 * Returns the foreground pattern. The default value is
 * <code>null</code>.
 *
 * @return the receiver's foreground pattern
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see Pattern
 *
 * @since 3.1
 */
public Pattern getForegroundPattern() {
	if (handle == null) SWT.error(SWT.ERROR_WIDGET_DISPOSED);
	return data.foregroundPattern;
}

/**
 * Returns the GCData.
 * <p>
 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
 * API for <code>GC</code>. It is marked public only so that it
 * can be shared within the packages provided by SWT. It is not
 * available on all platforms, and should never be called from
 * application code.
 * </p>
 *
 * @return the receiver's GCData
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see GCData
 *
 * @noreference This method is not intended to be referenced by clients.
 *
 * @since 3.2
 */
public GCData getGCData() {
	if (handle == null) SWT.error(SWT.ERROR_WIDGET_DISPOSED);
	NSAutoreleasePool pool = checkGC(TRANSFORM | CLIPPING);
	uncheckGC(pool);
	return data;
}

/**
 * Returns the receiver's interpolation setting, which will be one of
 * <code>SWT.DEFAULT</code>, <code>SWT.NONE</code>,
 * <code>SWT.LOW</code> or <code>SWT.HIGH</code>.
 *
 * @return the receiver's interpolation setting
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @since 3.1
 */
public int getInterpolation() {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	int interpolation = (int)handle.imageInterpolation();
	switch (interpolation) {
		case OS.NSImageInterpolationDefault: return SWT.DEFAULT;
		case OS.NSImageInterpolationNone: return SWT.NONE;
		case OS.NSImageInterpolationLow: return SWT.LOW;
		case OS.NSImageInterpolationHigh: return SWT.HIGH;
	}
	return SWT.DEFAULT;
}

/**
 * Returns the receiver's line attributes.
 *
 * @return the line attributes used for drawing lines
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @since 3.3
 */
public LineAttributes getLineAttributes() {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	float[] dashes = null;
	if (data.lineDashes != null) {
		dashes = new float[data.lineDashes.length];
		System.arraycopy(data.lineDashes, 0, dashes, 0, dashes.length);
	}
	return new LineAttributes(data.lineWidth, data.lineCap, data.lineJoin, data.lineStyle, dashes, data.lineDashesOffset, data.lineMiterLimit);
}

/**
 * Returns the receiver's line cap style, which will be one
 * of the constants <code>SWT.CAP_FLAT</code>, <code>SWT.CAP_ROUND</code>,
 * or <code>SWT.CAP_SQUARE</code>.
 *
 * @return the cap style used for drawing lines
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @since 3.1
 */
public int getLineCap() {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	return data.lineCap;
}

/**
 * Returns the receiver's line dash style. The default value is
 * <code>null</code>.
 *
 * @return the line dash style used for drawing lines
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @since 3.1
 */
public int[] getLineDash() {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (data.lineDashes == null) return null;
	int[] lineDashes = new int[data.lineDashes.length];
	for (int i = 0; i < lineDashes.length; i++) {
		lineDashes[i] = (int)data.lineDashes[i];
	}
	return lineDashes;
}

/**
 * Returns the receiver's line join style, which will be one
 * of the constants <code>SWT.JOIN_MITER</code>, <code>SWT.JOIN_ROUND</code>,
 * or <code>SWT.JOIN_BEVEL</code>.
 *
 * @return the join style used for drawing lines
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @since 3.1
 */
public int getLineJoin() {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	return data.lineJoin;
}

/**
 * Returns the receiver's line style, which will be one
 * of the constants <code>SWT.LINE_SOLID</code>, <code>SWT.LINE_DASH</code>,
 * <code>SWT.LINE_DOT</code>, <code>SWT.LINE_DASHDOT</code> or
 * <code>SWT.LINE_DASHDOTDOT</code>.
 *
 * @return the style used for drawing lines
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public int getLineStyle() {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	return data.lineStyle;
}

/**
 * Returns the width that will be used when drawing lines
 * for all of the figure drawing operations (that is,
 * <code>drawLine</code>, <code>drawRectangle</code>,
 * <code>drawPolyline</code>, and so forth.
 *
 * @return the receiver's line width
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public int getLineWidth() {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	return (int)data.lineWidth;
}

/**
 * Returns the receiver's style information.
 * <p>
 * Note that the value which is returned by this method <em>may
 * not match</em> the value which was provided to the constructor
 * when the receiver was created. This can occur when the underlying
 * operating system does not support a particular combination of
 * requested styles.
 * </p>
 *
 * @return the style bits
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @since 2.1.2
 */
public int getStyle () {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	return data.style;
}

/**
 * Returns the receiver's text drawing anti-aliasing setting value,
 * which will be one of <code>SWT.DEFAULT</code>, <code>SWT.OFF</code> or
 * <code>SWT.ON</code>. Note that this controls anti-aliasing
 * <em>only</em> for text drawing operations.
 *
 * @return the anti-aliasing setting
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #getAntialias
 *
 * @since 3.1
 */
public int getTextAntialias() {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	return data.textAntialias;
}

// Internal methos that returns the topView of the Control. It's the same view that would be returned
// by Control.topView(). But, we don't use Control.topView() since classes in the graphics package
// are not supposed to reference the classes in widgets package.
NSView getTopView(NSView view) {
	if (view != null) {
		NSView contentView = view.superview();
		if (contentView != null && contentView.isKindOfClass(OS.class_NSClipView)) {
			NSView superView = contentView.superview();
			if (superView != null && superView.isKindOfClass(OS.class_NSScrollView)) {
				NSScrollView scrollView = new NSScrollView(superView.id);
				if (scrollView.documentView() != null) {
					if (scrollView.documentView().id == view.id) {
						return superView;
					}
				}
			}
		}
	}
	return view;
}

/**
 * Sets the parameter to the transform that is currently being
 * used by the receiver.
 *
 * @param transform the destination to copy the transform into
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the parameter is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the parameter has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see Transform
 *
 * @since 3.1
 */
public void getTransform (Transform transform) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (transform == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (transform.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	NSAffineTransform cmt = data.transform;
	if (cmt != null) {
		NSAffineTransformStruct struct = cmt.transformStruct();
		transform.handle.setTransformStruct(struct);
	} else {
		transform.setElements(1, 0, 0, 1, 0, 0);
	}
}

/**
 * Returns <code>true</code> if this GC is drawing in the mode
 * where the resulting color in the destination is the
 * <em>exclusive or</em> of the color values in the source
 * and the destination, and <code>false</code> if it is
 * drawing in the mode where the destination color is being
 * replaced with the source color value.
 *
 * @return <code>true</code> true if the receiver is in XOR mode, and false otherwise
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public boolean getXORMode() {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	return data.xorMode;
}

/**
 * Returns an integer hash code for the receiver. Any two
 * objects that return <code>true</code> when passed to
 * <code>equals</code> must return the same value for this
 * method.
 *
 * @return the receiver's hash
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #equals
 */
@Override
public int hashCode() {
	return handle != null ? (int)handle.id : 0;
}

void init(Drawable drawable, GCData data, long context) {
	if (data.foreground != null) data.state &= ~(FOREGROUND | FOREGROUND_FILL);
	if (data.background != null)  data.state &= ~BACKGROUND;
	if (data.font != null) data.state &= ~FONT;
	data.state &= ~DRAW_OFFSET;

	Image image = data.image;
	if (image != null) image.memGC = this;
	this.drawable = drawable;
	this.data = data;
	handle = new NSGraphicsContext(context);
	handle.retain();
	handle.saveGraphicsState();
	data.path = NSBezierPath.bezierPath();
	data.path.setWindingRule(data.fillRule == SWT.FILL_WINDING ? OS.NSNonZeroWindingRule : OS.NSEvenOddWindingRule);
	data.path.retain();
}

void initCGContext(long cgContext) {
	int state = data.state;
	if ((state & LINE_WIDTH) != 0) {
		OS.CGContextSetLineWidth(cgContext, data.lineWidth == 0 ?  1 : data.lineWidth);
		switch (data.lineStyle) {
			case SWT.LINE_DOT:
			case SWT.LINE_DASH:
			case SWT.LINE_DASHDOT:
			case SWT.LINE_DASHDOTDOT:
				state |= LINE_STYLE;
		}
	}
	if ((state & LINE_STYLE) != 0) {
		float[] dashes = null;
		float width = data.lineWidth;
		switch (data.lineStyle) {
			case SWT.LINE_SOLID: break;
			case SWT.LINE_DASH: dashes = width != 0 ? LINE_DASH : LINE_DASH_ZERO; break;
			case SWT.LINE_DOT: dashes = width != 0 ? LINE_DOT : LINE_DOT_ZERO; break;
			case SWT.LINE_DASHDOT: dashes = width != 0 ? LINE_DASHDOT : LINE_DASHDOT_ZERO; break;
			case SWT.LINE_DASHDOTDOT: dashes = width != 0 ? LINE_DASHDOTDOT : LINE_DASHDOTDOT_ZERO; break;
			case SWT.LINE_CUSTOM: dashes = data.lineDashes; break;
		}
		if (dashes != null) {
			double[] lengths = new double[dashes.length];
			for (int i = 0; i < lengths.length; i++) {
				lengths[i] = width == 0 || data.lineStyle == SWT.LINE_CUSTOM ? dashes[i] : dashes[i] * width;
			}
			OS.CGContextSetLineDash(cgContext, data.lineDashesOffset, lengths, lengths.length);
		} else {
			OS.CGContextSetLineDash(cgContext, 0, null, 0);
		}
	}
	if ((state & LINE_MITERLIMIT) != 0) {
		OS.CGContextSetMiterLimit(cgContext, data.lineMiterLimit);
	}
	if ((state & LINE_JOIN) != 0) {
		int joinStyle = 0;
		switch (data.lineJoin) {
			case SWT.JOIN_MITER: joinStyle = OS.kCGLineJoinMiter; break;
			case SWT.JOIN_ROUND: joinStyle = OS.kCGLineJoinRound; break;
			case SWT.JOIN_BEVEL: joinStyle = OS.kCGLineJoinBevel; break;
		}
		OS.CGContextSetLineJoin(cgContext, joinStyle);
	}
	if ((state & LINE_CAP) != 0) {
		int capStyle = 0;
		switch (data.lineCap) {
			case SWT.CAP_ROUND: capStyle = OS.kCGLineCapRound; break;
			case SWT.CAP_FLAT: capStyle = OS.kCGLineCapButt; break;
			case SWT.CAP_SQUARE: capStyle = OS.kCGLineCapSquare; break;
		}
		OS.CGContextSetLineCap(cgContext, capStyle);
	}
}

/**
 * Returns <code>true</code> if the receiver has a clipping
 * region set into it, and <code>false</code> otherwise.
 * If this method returns false, the receiver will draw on all
 * available space in the destination. If it returns true,
 * it will draw only in the area that is covered by the region
 * that can be accessed with <code>getClipping(region)</code>.
 *
 * @return <code>true</code> if the GC has a clipping region, and <code>false</code> otherwise
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public boolean isClipped() {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	return data.clipPath != null;
}

/**
 * Returns <code>true</code> if the GC has been disposed,
 * and <code>false</code> otherwise.
 * <p>
 * This method gets the dispose state for the GC.
 * When a GC has been disposed, it is an error to
 * invoke any other method (except {@link #dispose()}) using the GC.
 *
 * @return <code>true</code> when the GC is disposed and <code>false</code> otherwise
 */
@Override
public boolean isDisposed() {
	return handle == null;
}

boolean isIdentity(float[] transform) {
	return transform[0] == 1 && transform[1] == 0 && transform[2] == 0
		&& transform[3] == 1 && transform[4] == 0 && transform[5] == 0;
}

/**
 * Sets the receiver to always use the operating system's advanced graphics
 * subsystem for all graphics operations if the argument is <code>true</code>.
 * If the argument is <code>false</code>, the advanced graphics subsystem is
 * no longer used, advanced graphics state is cleared and the normal graphics
 * subsystem is used from now on.
 * <p>
 * Normally, the advanced graphics subsystem is invoked automatically when
 * any one of the alpha, antialias, patterns, interpolation, paths, clipping
 * or transformation operations in the receiver is requested.  When the receiver
 * is switched into advanced mode, the advanced graphics subsystem performs both
 * advanced and normal graphics operations.  Because the two subsystems are
 * different, their output may differ.  Switching to advanced graphics before
 * any graphics operations are performed ensures that the output is consistent.
 * </p><p>
 * Advanced graphics may not be installed for the operating system.  In this
 * case, this operation does nothing.  Some operating system have only one
 * graphics subsystem, so switching from normal to advanced graphics does
 * nothing.  However, switching from advanced to normal graphics will always
 * clear the advanced graphics state, even for operating systems that have
 * only one graphics subsystem.
 * </p>
 *
 * @param advanced the new advanced graphics state
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @see #setAlpha
 * @see #setAntialias
 * @see #setBackgroundPattern
 * @see #setClipping(Path)
 * @see #setForegroundPattern
 * @see #setLineAttributes
 * @see #setInterpolation
 * @see #setTextAntialias
 * @see #setTransform
 * @see #getAdvanced
 *
 * @since 3.1
 */
public void setAdvanced(boolean advanced) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (!advanced) {
		setAlpha(0xFF);
		setAntialias(SWT.DEFAULT);
		setBackgroundPattern(null);
		setClipping((Rectangle)null);
		setForegroundPattern(null);
		setInterpolation(SWT.DEFAULT);
		setTextAntialias(SWT.DEFAULT);
		setTransform(null);
	}
}

/**
 * Sets the receiver's alpha value which must be
 * between 0 (transparent) and 255 (opaque).
 * <p>
 * This operation requires the operating system's advanced
 * graphics subsystem which may not be available on some
 * platforms.
 * </p>
 * @param alpha the alpha value
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li>
 * </ul>
 *
 * @see #getAdvanced
 * @see #setAdvanced
 *
 * @since 3.1
 */
public void setAlpha(int alpha) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	data.alpha = alpha & 0xFF;
	data.state &= ~(BACKGROUND | FOREGROUND | FOREGROUND_FILL);

}

/**
 * Sets the receiver's anti-aliasing value to the parameter,
 * which must be one of <code>SWT.DEFAULT</code>, <code>SWT.OFF</code>
 * or <code>SWT.ON</code>. Note that this controls anti-aliasing for all
 * <em>non-text drawing</em> operations.
 * <p>
 * This operation requires the operating system's advanced
 * graphics subsystem which may not be available on some
 * platforms.
 * </p>
 *
 * @param antialias the anti-aliasing setting
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the parameter is not one of <code>SWT.DEFAULT</code>,
 *                                 <code>SWT.OFF</code> or <code>SWT.ON</code></li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li>
 * </ul>
 *
 * @see #getAdvanced
 * @see #setAdvanced
 * @see #setTextAntialias
 *
 * @since 3.1
 */
public void setAntialias(int antialias) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	boolean mode = true;
	switch (antialias) {
		case SWT.DEFAULT:
			/* Printer is off by default */
			if (!handle.isDrawingToScreen()) mode = false;
			break;
		case SWT.OFF: mode = false; break;
		case SWT.ON: mode = true; break;
		default:
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	data.antialias = antialias;
	handle.setShouldAntialias(mode);
}

/**
 * Sets the background color. The background color is used
 * for fill operations and as the background color when text
 * is drawn.
 *
 * @param color the new background color for the receiver
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the color is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the color has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void setBackground(Color color) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (color == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (color.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	data.background = color.handle;
	data.backgroundPattern = null;
	if (data.bg != null) data.bg.release();
	data.bg = null;
	data.state &= ~BACKGROUND;
}

/**
 * Sets the background pattern. The default value is <code>null</code>.
 * <p>
 * This operation requires the operating system's advanced
 * graphics subsystem which may not be available on some
 * platforms.
 * </p>
 *
 * @param pattern the new background pattern
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the parameter has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li>
 * </ul>
 *
 * @see Pattern
 * @see #getAdvanced
 * @see #setAdvanced
 *
 * @since 3.1
 */
public void setBackgroundPattern(Pattern pattern) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (pattern != null && pattern.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	if (data.backgroundPattern == pattern) return;
	data.backgroundPattern = pattern;
	data.state &= ~BACKGROUND;
}

/**
 * Sets the area of the receiver which can be changed
 * by drawing operations to the rectangular area specified
 * by the arguments.
 *
 * @param x the x coordinate of the clipping rectangle
 * @param y the y coordinate of the clipping rectangle
 * @param width the width of the clipping rectangle
 * @param height the height of the clipping rectangle
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void setClipping(int x, int y, int width, int height) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	NSAutoreleasePool pool = null;
	if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
	try {
		if (width < 0) {
			x = x + width;
			width = -width;
		}
		if (height < 0) {
			y = y + height;
			height = -height;
		}
		NSRect rect = new NSRect();
		rect.x = x;
		rect.y = y;
		rect.width = width;
		rect.height = height;
		NSBezierPath path = NSBezierPath.bezierPathWithRect(rect);
		path.retain();
		setClipping(path);
	} finally {
		if (pool != null) pool.release();
	}
}

/**
 * Sets the area of the receiver which can be changed
 * by drawing operations to the path specified
 * by the argument.
 * <p>
 * This operation requires the operating system's advanced
 * graphics subsystem which may not be available on some
 * platforms.
 * </p>
 *
 * @param path the clipping path.
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the path has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li>
 * </ul>
 *
 * @see Path
 * @see #getAdvanced
 * @see #setAdvanced
 *
 * @since 3.1
 */
public void setClipping(Path path) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (path != null && path.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	NSAutoreleasePool pool = null;
	if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
	try {
		setClipping(new NSBezierPath(path.handle.copy().id));
	} finally {
		if (pool != null) pool.release();
	}
}

/**
 * Sets the area of the receiver which can be changed
 * by drawing operations to the rectangular area specified
 * by the argument.  Specifying <code>null</code> for the
 * rectangle reverts the receiver's clipping area to its
 * original value.
 *
 * @param rect the clipping rectangle or <code>null</code>
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void setClipping(Rectangle rect) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (rect == null) {
		setClipping((NSBezierPath)null);
	} else {
		setClipping(rect.x, rect.y, rect.width, rect.height);
	}
}

/**
 * Sets the area of the receiver which can be changed
 * by drawing operations to the region specified
 * by the argument.  Specifying <code>null</code> for the
 * region reverts the receiver's clipping area to its
 * original value.
 *
 * @param region the clipping region or <code>null</code>
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the region has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void setClipping(Region region) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (region != null && region.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	NSAutoreleasePool pool = null;
	if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
	try {
		setClipping(region != null ? region.getPath() : null);
	} finally {
		if (pool != null) pool.release();
	}
}

void setClipping(NSBezierPath path) {
	if (data.clipPath != null) {
		data.clipPath.release();
		data.clipPath = null;
	}
	if (path != null) {
		data.clipPath = path;
		if (data.transform != null) {
			data.clipPath.transformUsingAffineTransform(data.transform);
		}
	}
	data.state &= ~CLIPPING;
}

/**
 * Sets the receiver's fill rule to the parameter, which must be one of
 * <code>SWT.FILL_EVEN_ODD</code> or <code>SWT.FILL_WINDING</code>.
 *
 * @param rule the new fill rule
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the rule is not one of <code>SWT.FILL_EVEN_ODD</code>
 *                                 or <code>SWT.FILL_WINDING</code></li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @since 3.1
 */
public void setFillRule(int rule) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	switch (rule) {
		case SWT.FILL_WINDING:
		case SWT.FILL_EVEN_ODD: break;
		default:
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	data.fillRule = rule;
	data.path.setWindingRule(rule == SWT.FILL_WINDING ? OS.NSNonZeroWindingRule : OS.NSEvenOddWindingRule);
}

/**
 * Sets the font which will be used by the receiver
 * to draw and measure text to the argument. If the
 * argument is null, then a default font appropriate
 * for the platform will be used instead.
 *
 * @param font the new font for the receiver, or null to indicate a default font
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the font has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void setFont(Font font) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (font != null && font.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	data.font = font != null ? font : data.device.systemFont;
	data.state &= ~FONT;
}

/**
 * Sets the foreground color. The foreground color is used
 * for drawing operations including when text is drawn.
 *
 * @param color the new foreground color for the receiver
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the color is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the color has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void setForeground(Color color) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (color == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (color.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	data.foreground = color.handle;
	data.foregroundPattern = null;
	if (data.fg != null) data.fg.release();
	data.fg = null;
	data.state &= ~(FOREGROUND | FOREGROUND_FILL);
}

/**
 * Sets the foreground pattern. The default value is <code>null</code>.
 * <p>
 * This operation requires the operating system's advanced
 * graphics subsystem which may not be available on some
 * platforms.
 * </p>
 * @param pattern the new foreground pattern
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the parameter has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li>
 * </ul>
 *
 * @see Pattern
 * @see #getAdvanced
 * @see #setAdvanced
 *
 * @since 3.1
 */
public void setForegroundPattern(Pattern pattern) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (pattern != null && pattern.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	if (data.foregroundPattern == pattern) return;
	data.foregroundPattern = pattern;
	data.state &= ~(FOREGROUND | FOREGROUND_FILL);
}

/**
 * Sets the receiver's interpolation setting to the parameter, which
 * must be one of <code>SWT.DEFAULT</code>, <code>SWT.NONE</code>,
 * <code>SWT.LOW</code> or <code>SWT.HIGH</code>.
 * <p>
 * This operation requires the operating system's advanced
 * graphics subsystem which may not be available on some
 * platforms.
 * </p>
 *
 * @param interpolation the new interpolation setting
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the rule is not one of <code>SWT.DEFAULT</code>,
 *                                 <code>SWT.NONE</code>, <code>SWT.LOW</code> or <code>SWT.HIGH</code>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li>
 * </ul>
 *
 * @see #getAdvanced
 * @see #setAdvanced
 *
 * @since 3.1
 */
public void setInterpolation(int interpolation) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	int quality = 0;
	switch (interpolation) {
		case SWT.DEFAULT: quality = OS.NSImageInterpolationDefault; break;
		case SWT.NONE: quality = OS.NSImageInterpolationNone; break;
		case SWT.LOW: quality = OS.NSImageInterpolationLow; break;
		case SWT.HIGH: quality = OS.NSImageInterpolationHigh; break;
		default:
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	handle.setImageInterpolation(quality);
}

/**
 * Sets the receiver's line attributes.
 * <p>
 * This operation requires the operating system's advanced
 * graphics subsystem which may not be available on some
 * platforms.
 * </p>
 * @param attributes the line attributes
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the attributes is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if any of the line attributes is not valid</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li>
 * </ul>
 *
 * @see LineAttributes
 * @see #getAdvanced
 * @see #setAdvanced
 *
 * @since 3.3
 */
public void setLineAttributes(LineAttributes attributes) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (attributes == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	int mask = 0;
	float lineWidth = attributes.width;
	if (lineWidth != data.lineWidth) {
		mask |= LINE_WIDTH | DRAW_OFFSET;
	}
	int lineStyle = attributes.style;
	if (lineStyle != data.lineStyle) {
		mask |= LINE_STYLE;
		switch (lineStyle) {
			case SWT.LINE_SOLID:
			case SWT.LINE_DASH:
			case SWT.LINE_DOT:
			case SWT.LINE_DASHDOT:
			case SWT.LINE_DASHDOTDOT:
				break;
			case SWT.LINE_CUSTOM:
				if (attributes.dash == null) lineStyle = SWT.LINE_SOLID;
				break;
			default:
				SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		}
	}
	int join = attributes.join;
	if (join != data.lineJoin) {
		mask |= LINE_JOIN;
		switch (join) {
			case SWT.JOIN_MITER:
			case SWT.JOIN_ROUND:
			case SWT.JOIN_BEVEL:
				break;
			default:
				SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		}
	}
	int cap = attributes.cap;
	if (cap != data.lineCap) {
		mask |= LINE_CAP;
		switch (cap) {
			case SWT.CAP_FLAT:
			case SWT.CAP_ROUND:
			case SWT.CAP_SQUARE:
				break;
			default:
				SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		}
	}
	float[] dashes = attributes.dash;
	float[] lineDashes = data.lineDashes;
	if (dashes != null && dashes.length > 0) {
		boolean changed = lineDashes == null || lineDashes.length != dashes.length;
		for (int i = 0; i < dashes.length; i++) {
			float dash = dashes[i];
			if (dash <= 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
			if (!changed && lineDashes[i] != dash) changed = true;
		}
		if (changed) {
			float[] newDashes = new float[dashes.length];
			System.arraycopy(dashes, 0, newDashes, 0, dashes.length);
			dashes = newDashes;
			mask |= LINE_STYLE;
		} else {
			dashes = lineDashes;
		}
	} else {
		if (lineDashes != null && lineDashes.length > 0) {
			mask |= LINE_STYLE;
		} else {
			dashes = lineDashes;
		}
	}
	float dashOffset = attributes.dashOffset;
	if (dashOffset != data.lineDashesOffset) {
		mask |= LINE_STYLE;
	}
	float miterLimit = attributes.miterLimit;
	if (miterLimit != data.lineMiterLimit) {
		mask |= LINE_MITERLIMIT;
	}
	if (mask == 0) return;
	data.lineWidth = lineWidth;
	data.lineStyle = lineStyle;
	data.lineCap = cap;
	data.lineJoin = join;
	data.lineDashes = dashes;
	data.lineDashesOffset = dashOffset;
	data.lineMiterLimit = miterLimit;
	data.state &= ~mask;
}

/**
 * Sets the receiver's line cap style to the argument, which must be one
 * of the constants <code>SWT.CAP_FLAT</code>, <code>SWT.CAP_ROUND</code>,
 * or <code>SWT.CAP_SQUARE</code>.
 *
 * @param cap the cap style to be used for drawing lines
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the style is not valid</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @since 3.1
 */
public void setLineCap(int cap) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (data.lineCap == cap) return;
	switch (cap) {
		case SWT.CAP_ROUND:
		case SWT.CAP_FLAT:
		case SWT.CAP_SQUARE:
			break;
		default:
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	data.lineCap = cap;
	data.state &= ~LINE_CAP;
}

/**
 * Sets the receiver's line dash style to the argument. The default
 * value is <code>null</code>. If the argument is not <code>null</code>,
 * the receiver's line style is set to <code>SWT.LINE_CUSTOM</code>, otherwise
 * it is set to <code>SWT.LINE_SOLID</code>.
 *
 * @param dashes the dash style to be used for drawing lines
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if any of the values in the array is less than or equal 0</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @since 3.1
 */
public void setLineDash(int[] dashes) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	float[] lineDashes = data.lineDashes;
	if (dashes != null && dashes.length > 0) {
		boolean changed = data.lineStyle != SWT.LINE_CUSTOM || lineDashes == null || lineDashes.length != dashes.length;
		for (int i = 0; i < dashes.length; i++) {
			int dash = dashes[i];
			if (dash <= 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
			if (!changed && lineDashes[i] != dash) changed = true;
		}
		if (!changed) return;
		data.lineDashes = new float[dashes.length];
		for (int i = 0; i < dashes.length; i++) {
			data.lineDashes[i] = dashes[i];
		}
		data.lineStyle = SWT.LINE_CUSTOM;
	} else {
		if (data.lineStyle == SWT.LINE_SOLID && (lineDashes == null || lineDashes.length == 0)) return;
		data.lineDashes = null;
		data.lineStyle = SWT.LINE_SOLID;
	}
	data.state &= ~LINE_STYLE;
}

/**
 * Sets the receiver's line join style to the argument, which must be one
 * of the constants <code>SWT.JOIN_MITER</code>, <code>SWT.JOIN_ROUND</code>,
 * or <code>SWT.JOIN_BEVEL</code>.
 *
 * @param join the join style to be used for drawing lines
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the style is not valid</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 *
 * @since 3.1
 */
public void setLineJoin(int join) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (data.lineJoin == join) return;
	switch (join) {
		case SWT.JOIN_MITER:
		case SWT.JOIN_ROUND:
		case SWT.JOIN_BEVEL:
			break;
		default:
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	data.lineJoin = join;
	data.state &= ~LINE_JOIN;
}

/**
 * Sets the receiver's line style to the argument, which must be one
 * of the constants <code>SWT.LINE_SOLID</code>, <code>SWT.LINE_DASH</code>,
 * <code>SWT.LINE_DOT</code>, <code>SWT.LINE_DASHDOT</code> or
 * <code>SWT.LINE_DASHDOTDOT</code>.
 *
 * @param lineStyle the style to be used for drawing lines
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the style is not valid</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void setLineStyle(int lineStyle) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (data.lineStyle == lineStyle) return;
	switch (lineStyle) {
		case SWT.LINE_SOLID:
		case SWT.LINE_DASH:
		case SWT.LINE_DOT:
		case SWT.LINE_DASHDOT:
		case SWT.LINE_DASHDOTDOT:
			break;
		case SWT.LINE_CUSTOM:
			if (data.lineDashes == null) lineStyle = SWT.LINE_SOLID;
			break;
		default:
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	data.lineStyle = lineStyle;
	data.state &= ~LINE_STYLE;
}

/**
 * Sets the width that will be used when drawing lines
 * for all of the figure drawing operations (that is,
 * <code>drawLine</code>, <code>drawRectangle</code>,
 * <code>drawPolyline</code>, and so forth.
 * <p>
 * Note that line width of zero is used as a hint to
 * indicate that the fastest possible line drawing
 * algorithms should be used. This means that the
 * output may be different from line width one and
 * specially at high DPI it's not recommended to mix
 * line width zero with other line widths.
 * </p>
 *
 * @param lineWidth the width of a line
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void setLineWidth(int lineWidth) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (data.lineWidth == lineWidth) return;
	data.lineWidth = lineWidth;
	data.state &= ~(LINE_WIDTH | DRAW_OFFSET);
}

void setPatternPhase(Pattern pattern) {
	if (pattern.image == null) return;
	NSPoint phase = new NSPoint();
	if (data.image != null) {
		phase.y += data.image.handle.size().height - pattern.image.handle.size().height;
	} else if (data.view != null) {
		NSView view = data.view;
		if (!view.isFlipped()) {
			phase.y = view.bounds().height;
		}
		NSView contentView = view.window().contentView();
		phase = view.convertPoint_toView_(phase, contentView);
		phase.y = contentView.bounds().height - phase.y;
	} else if (data.size != null) {
		phase.y += data.size.height - pattern.image.handle.size().height;
	}
	handle.setPatternPhase(phase);
}

/**
 * If the argument is <code>true</code>, puts the receiver
 * in a drawing mode where the resulting color in the destination
 * is the <em>exclusive or</em> of the color values in the source
 * and the destination, and if the argument is <code>false</code>,
 * puts the receiver in a drawing mode where the destination color
 * is replaced with the source color value.
 *
 * @param xor if <code>true</code>, then <em>xor</em> mode is used, otherwise <em>source copy</em> mode is used
 *
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public void setXORMode(boolean xor) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	data.xorMode = xor;
}

/**
 * Sets the receiver's text anti-aliasing value to the parameter,
 * which must be one of <code>SWT.DEFAULT</code>, <code>SWT.OFF</code>
 * or <code>SWT.ON</code>. Note that this controls anti-aliasing only
 * for all <em>text drawing</em> operations.
 * <p>
 * This operation requires the operating system's advanced
 * graphics subsystem which may not be available on some
 * platforms.
 * </p>
 *
 * @param antialias the anti-aliasing setting
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the parameter is not one of <code>SWT.DEFAULT</code>,
 *                                 <code>SWT.OFF</code> or <code>SWT.ON</code></li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li>
 * </ul>
 *
 * @see #getAdvanced
 * @see #setAdvanced
 * @see #setAntialias
 *
 * @since 3.1
 */
public void setTextAntialias(int antialias) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	switch (antialias) {
		case SWT.DEFAULT:
		case SWT.OFF:
		case SWT.ON:
			break;
		default:
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	}
	data.textAntialias = antialias;
}

/**
 * Sets the transform that is currently being used by the receiver. If
 * the argument is <code>null</code>, the current transform is set to
 * the identity transform.
 * <p>
 * This operation requires the operating system's advanced
 * graphics subsystem which may not be available on some
 * platforms.
 * </p>
 *
 * @param transform the transform to set
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the parameter has been disposed</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li>
 * </ul>
 *
 * @see Transform
 * @see #getAdvanced
 * @see #setAdvanced
 *
 * @since 3.1
 */
public void setTransform(Transform transform) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (transform != null && transform.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	if (transform != null) {
		if (data.transform != null) data.transform.release();
		if (data.inverseTransform != null) data.inverseTransform.release();
		data.transform = ((NSAffineTransform)new NSAffineTransform().alloc()).initWithTransform(transform.handle);
		data.inverseTransform = ((NSAffineTransform)new NSAffineTransform().alloc()).initWithTransform(transform.handle);
		NSAffineTransformStruct struct = data.inverseTransform.transformStruct();
		if ((struct.m11 * struct.m22 - struct.m12 * struct.m21) != 0) {
			data.inverseTransform.invert();
		}
	} else {
		data.transform = data.inverseTransform = null;
	}
	data.state &= ~(TRANSFORM | DRAW_OFFSET);
}

/**
 * Returns the extent of the given string. No tab
 * expansion or carriage return processing will be performed.
 * <p>
 * The <em>extent</em> of a string is the width and height of
 * the rectangular area it would cover if drawn in a particular
 * font (in this case, the current font in the receiver).
 * </p>
 *
 * @param string the string to measure
 * @return a point containing the extent of the string
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the string is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public Point stringExtent(String string) {
	return textExtent(string, 0);
}

/**
 * Returns the extent of the given string. Tab expansion and
 * carriage return processing are performed.
 * <p>
 * The <em>extent</em> of a string is the width and height of
 * the rectangular area it would cover if drawn in a particular
 * font (in this case, the current font in the receiver).
 * </p>
 *
 * @param string the string to measure
 * @return a point containing the extent of the string
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the string is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public Point textExtent(String string) {
	return textExtent(string, SWT.DRAW_DELIMITER | SWT.DRAW_TAB);
}

/**
 * Returns the extent of the given string. Tab expansion, line
 * delimiter and mnemonic processing are performed according to
 * the specified flags, which can be a combination of:
 * <dl>
 * <dt><b>DRAW_DELIMITER</b></dt>
 * <dd>draw multiple lines</dd>
 * <dt><b>DRAW_TAB</b></dt>
 * <dd>expand tabs</dd>
 * <dt><b>DRAW_MNEMONIC</b></dt>
 * <dd>underline the mnemonic character</dd>
 * <dt><b>DRAW_TRANSPARENT</b></dt>
 * <dd>transparent background</dd>
 * </dl>
 * <p>
 * The <em>extent</em> of a string is the width and height of
 * the rectangular area it would cover if drawn in a particular
 * font (in this case, the current font in the receiver).
 * </p>
 *
 * @param string the string to measure
 * @param flags the flags specifying how to process the text
 * @return a point containing the extent of the string
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the string is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
 * </ul>
 */
public Point textExtent(String string, int flags) {
	if (handle == null) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
	if (string == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	NSAutoreleasePool pool = checkGC(FONT);
	try {
		int length = string.length();
		if (data.textStorage == null) createLayout();
		NSAttributedString attribStr = createString(length == 0 ? " " : string, flags, false); //$NON-NLS-1$
		data.textStorage.setAttributedString(attribStr);
		attribStr.release();
		data.layoutManager.glyphRangeForTextContainer(data.textContainer);
		NSRect rect = data.layoutManager.usedRectForTextContainer(data.textContainer);
		return new Point(length == 0 ? 0 : (int)Math.ceil(rect.width), (int)Math.ceil(rect.height));
	} finally {
		uncheckGC(pool);
	}
}

/**
 * Returns a string containing a concise, human-readable
 * description of the receiver.
 *
 * @return a string representation of the receiver
 */
@Override
public String toString () {
	if (isDisposed()) return "GC {*DISPOSED*}";
	return "GC {" + handle + "}";
}

void uncheckGC(NSAutoreleasePool pool) {
	if (data.flippedContext != null && data.restoreContext) {
		NSGraphicsContext.static_restoreGraphicsState();
		data.restoreContext = false;
	}
	NSView view = data.view;
	if (view != null && data.paintRect == null) {
		if (data.thread != Thread.currentThread()) flush();
	}
	if (pool != null) pool.release();
}

}
