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();
 }
+
+}