Mercurial > projects > dwt-mac
diff dwt/graphics/GC.d @ 45:d8635bb48c7c
Merge with SWT 3.5
author | Jacob Carlborg <doob@me.com> |
---|---|
date | Mon, 01 Dec 2008 17:07:00 +0100 |
parents | 642f460a0908 |
children | cfa563df4fdd |
line wrap: on
line diff
--- a/dwt/graphics/GC.d Tue Oct 21 15:20:04 2008 +0200 +++ b/dwt/graphics/GC.d Mon Dec 01 17:07:00 2008 +0100 @@ -1,5 +1,5 @@ -/******************************************************************************* - * Copyright (c) 2000, 2007 IBM Corporation and others. +/******************************************************************************* + * Copyright (c) 2000, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -9,7 +9,7 @@ * IBM Corporation - initial API and implementation * * Port to the D programming language: - * Jacob Carlborg <jacob.carlborg@gmail.com> + * Jacob Carlborg <doob@me.com> *******************************************************************************/ module dwt.graphics.GC; @@ -19,7 +19,9 @@ import dwt.DWTException; import dwt.internal.cocoa.NSAffineTransform; import dwt.internal.cocoa.NSAffineTransformStruct; +import dwt.internal.cocoa.NSArray; import dwt.internal.cocoa.NSAttributedString; +import dwt.internal.cocoa.NSAutoreleasePool; import dwt.internal.cocoa.NSBezierPath; import dwt.internal.cocoa.NSColor; import dwt.internal.cocoa.NSFont; @@ -28,10 +30,13 @@ import dwt.internal.cocoa.NSImage; import dwt.internal.cocoa.NSInteger; import dwt.internal.cocoa.NSMutableDictionary; +import dwt.internal.cocoa.NSMutableParagraphStyle; import dwt.internal.cocoa.NSPoint; import dwt.internal.cocoa.NSRect; import dwt.internal.cocoa.NSSize; import dwt.internal.cocoa.NSString; +import dwt.internal.cocoa.NSThread; +import dwt.internal.cocoa.NSView; import dwt.internal.cocoa.OS; import tango.text.convert.Format; @@ -85,6 +90,9 @@ * </p> * * @see dwt.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">DWT Examples: GraphicsExample, PaintExample</a> + * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> */ public final class GC : Resource { @@ -230,41 +238,46 @@ return gc; } -/** - * Invokes platform specific functionality to wrap a 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 DWT. It is not - * available on all platforms, and should never be called from - * application code. - * </p> - * - * @param context the Quartz context. - * @param data the data for the receiver. - * - * @return a new <code>GC</code> - */ -public static GC carbon_new(objc.id context, GCData data) { - GC gc = new GC(); - gc.device = data.device; - gc.init_(null, data, context); - return gc; -} - -void checkGC (int mask) { - if ((data.state & CLIPPING) is 0 || (data.state & TRANSFORM) is 0) { - handle.restoreGraphicsState(); - handle.saveGraphicsState(); - if (data.clipPath !is null) data.clipPath.addClip(); - if (data.transform !is null) data.transform.concat(); - mask &= ~(TRANSFORM | CLIPPING); - data.state |= TRANSFORM | CLIPPING; - data.state &= ~(BACKGROUND | FOREGROUND); +NSAutoreleasePool checkGC (int mask) { + NSAutoreleasePool pool = null; + if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); + if ((mask & (CLIPPING | TRANSFORM)) !is 0) { + NSGraphicsContext.setCurrentContext(handle); + NSView view = data.view; + if (view !is null && data.paintRect is null) { + NSRect rect = view.convertRect_toView_(view.bounds(), null); + NSRect visibleRect = view.visibleRect(); + if (data.windowRect is null || rect.x !is data.windowRect.x || rect.y !is data.windowRect.y || + rect.width !is data.windowRect.width || rect.height !is data.windowRect.height || + visibleRect.x !is data.visibleRect.x || visibleRect.y !is data.visibleRect.y || + visibleRect.width !is data.visibleRect.width || visibleRect.height !is data.visibleRect.height) + { + data.state &= ~CLIPPING; + data.windowRect = rect; + data.visibleRect = visibleRect; + } + } + if ((data.state & CLIPPING) is 0 || (data.state & TRANSFORM) is 0) { + handle.restoreGraphicsState(); + handle.saveGraphicsState(); + if (view !is null && data.paintRect is null) { + NSAffineTransform transform = NSAffineTransform.transform(); + NSRect rect = data.windowRect; + transform.translateXBy(rect.x, rect.y + rect.height); + transform.scaleXBy(1, -1); + transform.concat(); + NSBezierPath.bezierPathWithRect(data.visibleRect).addClip(); + } + if (data.clipPath !is null) data.clipPath.addClip(); + if (data.transform !is null) data.transform.concat(); + mask &= ~(TRANSFORM | CLIPPING); + data.state |= TRANSFORM | CLIPPING; + data.state &= ~(BACKGROUND | FOREGROUND); + } } int state = data.state; - if ((state & mask) is mask) return; + if ((state & mask) is mask) return pool; state = (state ^ mask) & mask; data.state |= mask; @@ -370,6 +383,7 @@ data.drawYOffset = 0.5f / scaling; } } + return pool; } /** @@ -646,53 +660,61 @@ NSMutableDictionary dict = NSMutableDictionary.dictionaryWithCapacity(4); CGFloat[] foreground = data.foreground; NSColor color = NSColor.colorWithDeviceRed(foreground[0], foreground[1], foreground[2], data.alpha / 255f); - dict.setObject(color, OS.NSForegroundColorAttributeName()); - dict.setObject(data.font.handle, OS.NSFontAttributeName()); + dict.setObject(color, OS.NSForegroundColorAttributeName); + dict.setObject(data.font.handle, OS.NSFontAttributeName); if ((flags & DWT.DRAW_TRANSPARENT) is 0) { CGFloat[] background = data.background; color = NSColor.colorWithDeviceRed(background[0], background[1], background[2], data.alpha / 255f); dict.setObject(color, OS.FuncNSBackgroundColorAttributeName()); } + if ((flags & DWT.DRAW_TAB) is 0) { + NSMutableParagraphStyle paragraph = (NSMutableParagraphStyle)new NSMutableParagraphStyle().alloc().init(); + paragraph.setAlignment(OS.NSLeftTextAlignment); + paragraph.setLineBreakMode(OS.NSLineBreakByClipping); + paragraph.setTabStops(NSArray.array()); + dict.setObject(paragraph, OS.NSParagraphStyleAttributeName); + paragraph.release(); + } size_t length = string.length(); char[] chars = new char[length]; string.getChars(0, length, chars, 0); -// int breakCount = 0; -// int[] breaks = null; -// if ((flags & (DWT.DRAW_MNEMONIC | DWT.DRAW_DELIMITER)) !is 0) { -// int i=0, j=0; -// while (i < chars.length) { -// char c = chars [j++] = chars [i++]; -// switch (c) { -// case '&': { -// if ((flags & DWT.DRAW_MNEMONIC) !is 0) { -// if (i is chars.length) {continue;} -// if (chars [i] is '&') {i++; continue;} -// j--; -// } -// break; -// } -// case '\r': -// case '\n': { -// if ((flags & DWT.DRAW_DELIMITER) !is 0) { -// if (c is '\r' && i !is chars.length && chars[i] is '\n') i++; -// j--; -// if (breaks is null) { -// breaks = new int[4]; -// } else if (breakCount is breaks.length) { -// int[] newBreaks = new int[breaks.length + 4]; -// System.arraycopy(breaks, 0, newBreaks, 0, breaks.length); -// breaks = newBreaks; -// } -// breaks[breakCount++] = j; -// } -// break; -// } -// } -// } -// length = j; -// } + int breakCount = 0; + int[] breaks = null; + if ((flags & DWT.DRAW_MNEMONIC) !is 0 || (flags & DWT.DRAW_DELIMITER) is 0) { + int i=0, j=0; + while (i < chars.length) { + char c = chars [j++] = chars [i++]; + switch (c) { + case '&': { + if ((flags & DWT.DRAW_MNEMONIC) !is 0) { + if (i is chars.length) {continue;} + if (chars [i] is '&') {i++; continue;} + j--; + } + break; + } + case '\r': + case '\n': { + if ((flags & DWT.DRAW_DELIMITER) is 0) { + if (c is '\r' && i !is chars.length && chars[i] is '\n') i++; + j--; + if (breaks is null) { + breaks = new int[4]; + } else if (breakCount is breaks.length) { + int[] newBreaks = new int[breaks.length + 4]; + System.arraycopy(breaks, 0, newBreaks, 0, breaks.length); + breaks = newBreaks; + } + breaks[breakCount++] = j; + } + break; + } + } + } + length = j; + } NSString str = NSString.stringWithCharacters(chars.toCharArray().ptr, length); - return (cast(NSAttributedString)(new NSAttributedString()).alloc()).initWithString_attributes_(str, dict); + return (cast(NSAttributedString)(new NSAttributedString()).alloc()).initWithString(str, dict); } void destroy() { @@ -702,6 +724,7 @@ image.memGC = null; image.createAlpha(); } + if (data.path !is null) data.path.release(); if (data.clipPath !is null) data.clipPath.release(); if (data.transform !is null) data.transform.release(); if (data.inverseTransform !is null) data.inverseTransform.release(); @@ -750,9 +773,6 @@ */ public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - NSGraphicsContext context = NSGraphicsContext.currentContext(); - NSGraphicsContext.setCurrentContext(handle); - checkGC(DRAW); if (width < 0) { x = x + width; width = -width; @@ -762,21 +782,25 @@ height = -height; } if (width is 0 || height is 0 || arcAngle is 0) return; - handle.saveGraphicsState(); - NSAffineTransform transform = NSAffineTransform.transform(); + NSAutoreleasePool pool = checkGC(DRAW); + try { + handle.saveGraphicsState(); + NSAffineTransform transform = NSAffineTransform.transform(); CGFloat 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; + transform.translateXBy(x + xOffset + width / 2f, y + yOffset + height / 2f); + transform.scaleXBy(width / 2f, height / 2f); + NSBezierPath path = data.path; NSPoint center = NSPoint(); CGFloat sAngle = -startAngle; CGFloat eAngle = -(startAngle + arcAngle); - path.appendBezierPathWithArcWithCenter_radius_startAngle_endAngle_clockwise_(center, 1, sAngle, eAngle, arcAngle>0); - path.transformUsingAffineTransform(transform); - path.stroke(); - path.removeAllPoints(); - handle.restoreGraphicsState(); - NSGraphicsContext.setCurrentContext(context); + path.appendBezierPathWithArcWithCenter(center, 1, sAngle, eAngle, arcAngle>0); + path.transformUsingAffineTransform(transform); + path.stroke(); + path.removeAllPoints(); + handle.restoreGraphicsState(); + } finally { + uncheckGC(pool); + } } /** @@ -798,19 +822,19 @@ */ public void drawFocus(int x, int y, int width, int height) { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - NSGraphicsContext context = NSGraphicsContext.currentContext(); - NSGraphicsContext.setCurrentContext(handle); - checkGC(CLIPPING | TRANSFORM); -// int[] metric = new int[1]; -// OS.GetThemeMetric(OS.kThemeMetricFocusRectOutset, metric); -// CGRect rect = new CGRect (); -// rect.x = x + metric[0]; -// rect.y = y + metric[0]; -// rect.width = width - metric[0] * 2; -// rect.height = height - metric[0] * 2; -// OS.HIThemeDrawFocusRect(rect, true, handle, OS.kHIThemeOrientationNormal); -// flush(); - NSGraphicsContext.setCurrentContext(context); + NSAutoreleasePool pool = checkGC(CLIPPING | TRANSFORM); + try { + // int[] metric = new int[1]; + // OS.GetThemeMetric(OS.kThemeMetricFocusRectOutset, metric); + // CGRect rect = new CGRect (); + // rect.x = x + metric[0]; + // rect.y = y + metric[0]; + // rect.width = width - metric[0] * 2; + // rect.height = height - metric[0] * 2; + // OS.HIThemeDrawFocusRect(rect, true, handle, OS.kHIThemeOrientationNormal); + } finally { + uncheckGC(pool); + } } /** @@ -883,9 +907,6 @@ } void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, bool simple) { - NSGraphicsContext context = NSGraphicsContext.currentContext(); - NSGraphicsContext.setCurrentContext(handle); - checkGC(CLIPPING | TRANSFORM); NSImage imageHandle = srcImage.handle; NSSize size = imageHandle.size(); int imgWidth = cast(int)size.width; @@ -898,29 +919,34 @@ srcWidth is destWidth && destWidth is imgWidth && srcHeight is destHeight && destHeight is imgHeight; if (srcX + srcWidth > imgWidth || srcY + srcHeight > imgHeight) { - NSGraphicsContext.setCurrentContext(context); DWT.error(DWT.ERROR_INVALID_ARGUMENT); } } - if (srcImage.memGC !is null) srcImage.createAlpha(); - handle.saveGraphicsState(); - NSAffineTransform transform = NSAffineTransform.transform(); - transform.scaleXBy(1, -1); - transform.translateXBy(0, -(destHeight + 2 * destY)); - transform.concat(); + NSAutoreleasePool pool = checkGC(CLIPPING | TRANSFORM); + try { + if (srcImage.memGC !is null) { + srcImage.createAlpha(); + } + handle.saveGraphicsState(); + NSAffineTransform transform = NSAffineTransform.transform(); + transform.scaleXBy(1, -1); + transform.translateXBy(0, -(destHeight + 2 * destY)); + transform.concat(); NSRect srcRect = NSRect(); - srcRect.x = srcX; - srcRect.y = srcY; - srcRect.width = srcWidth; - srcRect.height = srcHeight; + srcRect.x = srcX; + srcRect.y = imgHeight - (srcY + srcHeight); + srcRect.width = srcWidth; + srcRect.height = srcHeight; NSRect destRect = NSRect(); - destRect.x = destX; - destRect.y = destY; - destRect.width = destWidth; - destRect.height = destHeight; + destRect.x = destX; + destRect.y = destY; + destRect.width = destWidth; + destRect.height = destHeight; imageHandle.drawInRect(destRect, srcRect, NSCompositeSourceOver, 1); - handle.restoreGraphicsState(); - NSGraphicsContext.setCurrentContext(context); + handle.restoreGraphicsState(); + } finally { + uncheckGC(pool); + } } /** @@ -938,20 +964,21 @@ */ public void drawLine(int x1, int y1, int x2, int y2) { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - NSGraphicsContext context = NSGraphicsContext.currentContext(); - NSGraphicsContext.setCurrentContext(handle); - checkGC(DRAW); - NSBezierPath path = data.path; + NSAutoreleasePool pool = checkGC(DRAW); + try { + NSBezierPath path = data.path; NSPoint pt = 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); - path.stroke(); - path.removeAllPoints(); - NSGraphicsContext.setCurrentContext(context); + 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); + path.stroke(); + path.removeAllPoints(); + } finally { + uncheckGC(pool); + } } /** @@ -977,27 +1004,28 @@ */ public void drawOval(int x, int y, int width, int height) { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - NSGraphicsContext context = NSGraphicsContext.currentContext(); - NSGraphicsContext.setCurrentContext(handle); - checkGC(DRAW); - if (width < 0) { - x = x + width; - width = -width; - } - if (height < 0) { - y = y + height; - height = -height; + 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 = NSRect(); + rect.x = x + data.drawXOffset; + rect.y = y + data.drawXOffset; + rect.width = width; + rect.height = height; + path.appendBezierPathWithOvalInRect(rect); + path.stroke(); + path.removeAllPoints(); + } finally { + uncheckGC(pool); } - NSBezierPath path = data.path; - NSRect rect = NSRect(); - rect.x = x + data.drawXOffset; - rect.y = y + data.drawXOffset; - rect.width = width; - rect.height = height; - path.appendBezierPathWithOvalInRect(rect); - path.stroke(); - path.removeAllPoints(); - NSGraphicsContext.setCurrentContext(context); } /** @@ -1027,19 +1055,20 @@ if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); if (path is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); if (path.handle is null) DWT.error(DWT.ERROR_INVALID_ARGUMENT); - NSGraphicsContext context = NSGraphicsContext.currentContext(); - NSGraphicsContext.setCurrentContext(handle); - checkGC(DRAW); - handle.saveGraphicsState(); - NSAffineTransform transform = NSAffineTransform.transform(); - transform.translateXBy(data.drawXOffset, data.drawYOffset); - transform.concat(); - NSBezierPath drawPath = data.path; - drawPath.appendBezierPath(path.handle); - drawPath.stroke(); - drawPath.removeAllPoints(); - handle.restoreGraphicsState(); - NSGraphicsContext.setCurrentContext(context); + 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); + drawPath.stroke(); + drawPath.removeAllPoints(); + handle.restoreGraphicsState(); + } finally { + uncheckGC(pool); + } } /** @@ -1061,19 +1090,20 @@ */ public void drawPoint(int x, int y) { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - NSGraphicsContext context = NSGraphicsContext.currentContext(); - NSGraphicsContext.setCurrentContext(handle); - checkGC(FOREGROUND_FILL); + NSAutoreleasePool pool = checkGC(FOREGROUND_FILL | CLIPPING | TRANSFORM); + try { NSRect rect = NSRect(); - rect.x = x; - rect.y = y; - rect.width = 1; - rect.height = 1; - NSBezierPath path = data.path; - path.appendBezierPathWithRect(rect); - path.fill(); - path.removeAllPoints(); - NSGraphicsContext.setCurrentContext(context); + 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); + } } /** @@ -1096,26 +1126,27 @@ public void drawPolygon(int[] pointArray) { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); if (pointArray is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); - NSGraphicsContext context = NSGraphicsContext.currentContext(); - NSGraphicsContext.setCurrentContext(handle); - checkGC(DRAW); if (pointArray.length < 4) return; - CGFloat xOffset = data.drawXOffset, yOffset = data.drawYOffset; - NSBezierPath path = data.path; + NSAutoreleasePool pool = checkGC(DRAW); + try { + float /*double*/ xOffset = data.drawXOffset, yOffset = data.drawYOffset; + NSBezierPath path = data.path; NSPoint pt = 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); + 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(); + path.stroke(); + path.removeAllPoints(); + } finally { + uncheckGC(pool); } - path.closePath(); - path.stroke(); - path.removeAllPoints(); - NSGraphicsContext.setCurrentContext(context); } /** @@ -1138,25 +1169,26 @@ public void drawPolyline(int[] pointArray) { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); if (pointArray is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); - NSGraphicsContext context = NSGraphicsContext.currentContext(); - NSGraphicsContext.setCurrentContext(handle); - checkGC(DRAW); if (pointArray.length < 4) return; - CGFloat xOffset = data.drawXOffset, yOffset = data.drawYOffset; - NSBezierPath path = data.path; + NSAutoreleasePool pool = checkGC(DRAW); + try { + float /*double*/ xOffset = data.drawXOffset, yOffset = data.drawYOffset; + NSBezierPath path = data.path; NSPoint pt = 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); + 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.stroke(); + path.removeAllPoints(); + } finally { + uncheckGC(pool); } - path.stroke(); - path.removeAllPoints(); - NSGraphicsContext.setCurrentContext(context); } /** @@ -1176,27 +1208,28 @@ */ public void drawRectangle(int x, int y, int width, int height) { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - NSGraphicsContext context = NSGraphicsContext.currentContext(); - NSGraphicsContext.setCurrentContext(handle); - checkGC(DRAW); - if (width < 0) { - x = x + width; - width = -width; - } - if (height < 0) { - y = y + height; - height = -height; + NSAutoreleasePool pool = checkGC(DRAW); + try { + if (width < 0) { + x = x + width; + width = -width; + } + if (height < 0) { + y = y + height; + height = -height; + } + NSRect rect = NSRect(); + rect.x = x + data.drawXOffset; + rect.y = y + data.drawYOffset; + rect.width = width; + rect.height = height; + NSBezierPath path = data.path; + path.appendBezierPathWithRect(rect); + path.stroke(); + path.removeAllPoints(); + } finally { + uncheckGC(pool); } - NSRect rect = NSRect(); - rect.x = x + data.drawXOffset; - rect.y = y + data.drawYOffset; - rect.width = width; - rect.height = height; - NSBezierPath path = data.path; - path.appendBezierPathWithRect(rect); - path.stroke(); - path.removeAllPoints(); - NSGraphicsContext.setCurrentContext(context); } /** @@ -1244,24 +1277,24 @@ */ public void drawRoundRectangle(int x, int y, int width, int height, int arcWidth, int arcHeight) { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - NSGraphicsContext context = NSGraphicsContext.currentContext(); - NSGraphicsContext.setCurrentContext(handle); - checkGC(DRAW); if (arcWidth is 0 || arcHeight is 0) { drawRectangle(x, y, width, height); - NSGraphicsContext.setCurrentContext(context); return; } - NSBezierPath path = data.path; + NSAutoreleasePool pool = checkGC(DRAW); + try { + NSBezierPath path = data.path; NSRect rect = NSRect(); - rect.x = x + data.drawXOffset; - rect.y = y + data.drawYOffset; - rect.width = width; - rect.height = height; - path.appendBezierPathWithRoundedRect(rect, arcWidth, arcHeight); - path.stroke(); - path.removeAllPoints(); - NSGraphicsContext.setCurrentContext(context); + rect.x = x + data.drawXOffset; + rect.y = y + data.drawYOffset; + rect.width = width; + rect.height = height; + path.appendBezierPathWithRoundedRect(rect, arcWidth, arcHeight); + path.stroke(); + path.removeAllPoints(); + } finally { + uncheckGC(pool); + } } /** @@ -1395,26 +1428,27 @@ public void drawText (String string, int x, int y, int flags) { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); if (string is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); - NSGraphicsContext context = NSGraphicsContext.currentContext(); - NSGraphicsContext.setCurrentContext(handle); - checkGC(CLIPPING | TRANSFORM | FONT | FOREGROUND_FILL); - NSAttributedString str = createString(string, flags); - if (data.paintRect is null) { - handle.saveGraphicsState(); - NSAffineTransform transform = NSAffineTransform.transform(); - transform.scaleXBy(1, -1); - transform.translateXBy(0, -(str.size().height + 2 * y)); - transform.concat(); + NSAutoreleasePool pool = checkGC(CLIPPING | TRANSFORM | FONT | FOREGROUND_FILL); + try { + NSAttributedString str = createString(string, flags); + if (data.paintRect is null) { + handle.saveGraphicsState(); + NSAffineTransform transform = NSAffineTransform.transform(); + transform.scaleXBy(1, -1); + transform.translateXBy(0, -(str.size().height + 2 * y)); + transform.concat(); + } + NSPoint pt = NSPoint(); + pt.x = x; + pt.y = y; + str.drawAtPoint(pt); + str.release(); + if (data.paintRect is null) { + handle.restoreGraphicsState(); + } + } finally { + uncheckGC(pool); } - NSPoint pt = NSPoint(); - pt.x = x; - pt.y = y; - str.drawAtPoint(pt); - str.release(); - if (data.paintRect is null) { - handle.restoreGraphicsState(); - } - NSGraphicsContext.setCurrentContext(context); } /** @@ -1469,9 +1503,6 @@ */ public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - NSGraphicsContext context = NSGraphicsContext.currentContext(); - NSGraphicsContext.setCurrentContext(handle); - checkGC(FILL); if (width < 0) { x = x + width; width = -width; @@ -1481,23 +1512,27 @@ height = -height; } if (width is 0 || height is 0 || arcAngle is 0) return; - handle.saveGraphicsState(); - NSAffineTransform transform = NSAffineTransform.transform(); + NSAutoreleasePool pool = checkGC(FILL); + try { + handle.saveGraphicsState(); + NSAffineTransform transform = NSAffineTransform.transform(); CGFloat 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; + transform.translateXBy(x + xOffset + width / 2f, y + yOffset + height / 2f); + transform.scaleXBy(width / 2f, height / 2f); + NSBezierPath path = data.path; NSPoint center = NSPoint(); - path.moveToPoint(center); + path.moveToPoint(center); CGFloat sAngle = -startAngle; CGFloat eAngle = -(startAngle + arcAngle); - path.appendBezierPathWithArcWithCenter_radius_startAngle_endAngle_clockwise_(center, 1, sAngle, eAngle, arcAngle>0); - path.closePath(); - path.transformUsingAffineTransform(transform); - path.fill(); - path.removeAllPoints(); - handle.restoreGraphicsState(); - NSGraphicsContext.setCurrentContext(context); + path.appendBezierPathWithArcWithCenter(center, 1, sAngle, eAngle, arcAngle>0); + path.closePath(); + path.transformUsingAffineTransform(transform); + path.fill(); + path.removeAllPoints(); + handle.restoreGraphicsState(); + } finally { + uncheckGC(pool); + } } /** @@ -1522,46 +1557,46 @@ */ public void fillGradientRectangle(int x, int y, int width, int height, bool vertical) { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - NSGraphicsContext context = NSGraphicsContext.currentContext(); - NSGraphicsContext.setCurrentContext(handle); - checkGC(CLIPPING | TRANSFORM); if ((width is 0) || (height is 0)) return; - - RGB backgroundRGB, foregroundRGB; - backgroundRGB = getBackground().getRGB(); - foregroundRGB = getForeground().getRGB(); + NSAutoreleasePool pool = checkGC(CLIPPING | TRANSFORM); + try { + RGB backgroundRGB, foregroundRGB; + backgroundRGB = getBackground().getRGB(); + foregroundRGB = getForeground().getRGB(); - RGB fromRGB, toRGB; - fromRGB = foregroundRGB; - toRGB = backgroundRGB; - bool 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); + RGB fromRGB, toRGB; + fromRGB = foregroundRGB; + toRGB = backgroundRGB; + bool 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 = (cast(NSGradient)(new NSGradient()).alloc()).initWithStartingColor(startingColor, endingColor); NSRect rect = NSRect(); - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - gradient.drawInRect_angle_(rect, vertical ? 90 : 0); - gradient.release(); + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + gradient.drawInRect(rect, vertical ? 90 : 0); + gradient.release(); + } + } finally { + uncheckGC(pool); } - NSGraphicsContext.setCurrentContext(context); } /** @@ -1582,40 +1617,40 @@ */ public void fillOval(int x, int y, int width, int height) { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - NSGraphicsContext context = NSGraphicsContext.currentContext(); - NSGraphicsContext.setCurrentContext(handle); - checkGC(FILL); - if (width < 0) { - x = x + width; - width = -width; - } - if (height < 0) { - y = y + height; - height = -height; - } - NSBezierPath path = data.path; + 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 = NSRect(); - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - path.appendBezierPathWithOvalInRect(rect); - Pattern pattern = data.backgroundPattern; - if (pattern !is null && pattern.gradient !is null) { - fillPattern(path, pattern); - } else { - path.fill(); + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + path.appendBezierPathWithOvalInRect(rect); + Pattern pattern = data.backgroundPattern; + if (pattern !is null && pattern.gradient !is null) { + fillPattern(path, pattern); + } else { + path.fill(); + } + path.removeAllPoints(); + } finally { + uncheckGC(pool); } - path.removeAllPoints(); - NSGraphicsContext.setCurrentContext(context); } void fillPattern(NSBezierPath path, Pattern pattern) { - NSGraphicsContext context = NSGraphicsContext.currentContext(); - NSGraphicsContext.setCurrentContext(handle); + handle.saveGraphicsState(); path.addClip(); pattern.gradient.drawFromPoint(pattern.pt1, pattern.pt2, OS.NSGradientDrawsAfterEndingLocation | OS.NSGradientDrawsBeforeStartingLocation); - NSGraphicsContext.setCurrentContext(context); + handle.restoreGraphicsState(); } /** @@ -1645,19 +1680,20 @@ if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); if (path is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); if (path.handle is null) DWT.error(DWT.ERROR_INVALID_ARGUMENT); - NSGraphicsContext context = NSGraphicsContext.currentContext(); - NSGraphicsContext.setCurrentContext(handle); - checkGC(FILL); - NSBezierPath drawPath = data.path; - drawPath.appendBezierPath(path.handle); - Pattern pattern = data.backgroundPattern; - if (pattern !is null && pattern.gradient !is null) { - fillPattern(drawPath, pattern); - } else { - drawPath.fill(); + NSAutoreleasePool pool = checkGC(FILL); + try { + NSBezierPath drawPath = data.path; + drawPath.appendBezierPath(path.handle); + Pattern pattern = data.backgroundPattern; + if (pattern !is null && pattern.gradient !is null) { + fillPattern(drawPath, pattern); + } else { + drawPath.fill(); + } + drawPath.removeAllPoints(); + } finally { + uncheckGC(pool); } - drawPath.removeAllPoints(); - NSGraphicsContext.setCurrentContext(context); } /** @@ -1682,30 +1718,31 @@ public void fillPolygon(int[] pointArray) { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); if (pointArray is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); - NSGraphicsContext context = NSGraphicsContext.currentContext(); - NSGraphicsContext.setCurrentContext(handle); - checkGC(FILL); if (pointArray.length < 4) return; - NSBezierPath path = data.path; + NSAutoreleasePool pool = checkGC(FILL); + try { + NSBezierPath path = data.path; NSPoint pt = 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); + 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 !is null && pattern.gradient !is null) { + fillPattern(path, pattern); + } else { + path.fill(); + } + path.removeAllPoints(); + } finally { + uncheckGC(pool); } - path.closePath(); - Pattern pattern = data.backgroundPattern; - if (pattern !is null && pattern.gradient !is null) { - fillPattern(path, pattern); - } else { - path.fill(); - } - path.removeAllPoints(); - NSGraphicsContext.setCurrentContext(context); } /** @@ -1725,32 +1762,33 @@ */ public void fillRectangle(int x, int y, int width, int height) { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - NSGraphicsContext context = NSGraphicsContext.currentContext(); - NSGraphicsContext.setCurrentContext(handle); - checkGC(FILL); - if (width < 0) { - x = x + width; - width = -width; - } - if (height < 0) { - y = y + height; - height = -height; - } + NSAutoreleasePool pool = checkGC(FILL); + try { + if (width < 0) { + x = x + width; + width = -width; + } + if (height < 0) { + y = y + height; + height = -height; + } NSRect rect = 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 !is null && pattern.gradient !is null) { - fillPattern(path, pattern); - } else { - path.fill(); + 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 !is null && pattern.gradient !is null) { + fillPattern(path, pattern); + } else { + path.fill(); + } + path.removeAllPoints(); + } finally { + uncheckGC(pool); } - path.removeAllPoints(); - NSGraphicsContext.setCurrentContext(context); } /** @@ -1793,31 +1831,33 @@ */ public void fillRoundRectangle(int x, int y, int width, int height, int arcWidth, int arcHeight) { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - NSGraphicsContext context = NSGraphicsContext.currentContext(); - NSGraphicsContext.setCurrentContext(handle); - checkGC(FILL); if (arcWidth is 0 || arcHeight is 0) { fillRectangle(x, y, width, height); return; } - NSBezierPath path = data.path; + NSAutoreleasePool pool = checkGC(FILL); + try { + NSBezierPath path = data.path; NSRect rect = NSRect(); - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - path.appendBezierPathWithRoundedRect(rect, arcWidth, arcHeight); - Pattern pattern = data.backgroundPattern; - if (pattern !is null && pattern.gradient !is null) { - fillPattern(path, pattern); - } else { - path.fill(); + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + path.appendBezierPathWithRoundedRect(rect, arcWidth, arcHeight); + Pattern pattern = data.backgroundPattern; + if (pattern !is null && pattern.gradient !is null) { + fillPattern(path, pattern); + } else { + path.fill(); + } + path.removeAllPoints(); + } finally { + uncheckGC(pool); } - path.removeAllPoints(); - NSGraphicsContext.setCurrentContext(context); } void flush () { + handle.flushGraphics(); } /** @@ -1905,7 +1945,8 @@ } /** - * Returns the receiver's alpha value. + * Returns the receiver's alpha value. The alpha value + * is between 0 (transparent) and 255 (opaque). * * @return the alpha value * @@ -1979,7 +2020,7 @@ if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); NSRect rect; if (data.view !is null) { - rect = data.view.bounds(); + rect = data.view.visibleRect(); } else { rect = NSRect(); if (data.image !is null) { @@ -2038,7 +2079,7 @@ region.subtract(region); NSRect rect = void; if (data.view !is null) { - rect = data.view.bounds(); + rect = data.view.visibleRect(); } else { rect = NSRect(); if (data.image !is null) { @@ -2057,7 +2098,7 @@ } if (data.clipPath !is null) { NSBezierPath clip = data.clipPath.bezierPathByFlatteningPath(); - int count = clip.elementCount(); + int count = (int)/*64*/clip.elementCount(); int pointCount = 0; Region clipRgn = new Region(device); int[] pointArray = new int[count * 2]; @@ -2065,7 +2106,7 @@ if (points is null) DWT.error(DWT.ERROR_NO_HANDLES); NSPoint pt = NSPoint(); for (int i = 0; i < count; i++) { - NSBezierPathElement element = clip.elementAtIndex_associatedPoints_(i, points); + NSBezierPathElement element = clip.elementAtIndex(i, points); switch (element) { case NSMoveToBezierPathElement: if (pointCount !is 0) clipRgn.add(pointArray, pointCount); @@ -2140,13 +2181,17 @@ */ public FontMetrics getFontMetrics() { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - checkGC(FONT); - NSFont font = data.font.handle; + NSAutoreleasePool pool = checkGC(FONT); + try { + NSFont font = data.font.handle; int ascent = cast(int)(0.5f + font.ascender()); int descent = cast(int)(0.5f + (-font.descender() + font.leading())); - String s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - int averageCharWidth = stringExtent(s).x / s.length(); - return FontMetrics.cocoa_new(ascent, descent, averageCharWidth, 0, ascent + descent); + String s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + int averageCharWidth = stringExtent(s).x / s.length(); + return FontMetrics.cocoa_new(ascent, descent, averageCharWidth, 0, ascent + descent); + } finally { + uncheckGC(pool); + } } /** @@ -2222,7 +2267,7 @@ */ public int getInterpolation() { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); - int interpolation = handle.imageInterpolation(); + int interpolation = (int)/*64*/handle.imageInterpolation(); switch (interpolation) { case OS.NSImageInterpolationDefault: return DWT.DEFAULT; case OS.NSImageInterpolationNone: return DWT.NONE; @@ -2572,7 +2617,8 @@ } /** - * Sets the receiver's alpha value. + * 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 @@ -3437,10 +3483,14 @@ public Point textExtent(String string, int flags) { if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); if (string is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); - checkGC(FONT); - NSAttributedString str = createString(string, flags); - NSSize size = str.size(); + NSAutoreleasePool pool = checkGC(FONT); + try { + NSAttributedString str = createString(string, flags); + NSSize size = str.size(); return new Point(cast(int)size.width, cast(int)size.height); + } finally { + uncheckGC(pool); + } } /** @@ -3454,4 +3504,12 @@ return Format("GC {{}{}" , handle , "}"); } +void uncheckGC(NSAutoreleasePool pool) { + NSView view = data.view; + if (view !is null && data.paintRect is null) { + if (data.thread !is Thread.currentThread()) flush(); + } + if (pool !is null) pool.release(); } + +}