comparison 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
comparison
equal deleted inserted replaced
44:ca5e494f2bbf 45:d8635bb48c7c
1 /******************************************************************************* 1 /*******************************************************************************
2 * Copyright (c) 2000, 2007 IBM Corporation and others. 2 * Copyright (c) 2000, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials 3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0 4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at 5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html 6 * http://www.eclipse.org/legal/epl-v10.html
7 * 7 *
8 * Contributors: 8 * Contributors:
9 * IBM Corporation - initial API and implementation 9 * IBM Corporation - initial API and implementation
10 * 10 *
11 * Port to the D programming language: 11 * Port to the D programming language:
12 * Jacob Carlborg <jacob.carlborg@gmail.com> 12 * Jacob Carlborg <doob@me.com>
13 *******************************************************************************/ 13 *******************************************************************************/
14 module dwt.graphics.GC; 14 module dwt.graphics.GC;
15 15
16 16
17 import dwt.DWT; 17 import dwt.DWT;
18 import dwt.DWTError; 18 import dwt.DWTError;
19 import dwt.DWTException; 19 import dwt.DWTException;
20 import dwt.internal.cocoa.NSAffineTransform; 20 import dwt.internal.cocoa.NSAffineTransform;
21 import dwt.internal.cocoa.NSAffineTransformStruct; 21 import dwt.internal.cocoa.NSAffineTransformStruct;
22 import dwt.internal.cocoa.NSArray;
22 import dwt.internal.cocoa.NSAttributedString; 23 import dwt.internal.cocoa.NSAttributedString;
24 import dwt.internal.cocoa.NSAutoreleasePool;
23 import dwt.internal.cocoa.NSBezierPath; 25 import dwt.internal.cocoa.NSBezierPath;
24 import dwt.internal.cocoa.NSColor; 26 import dwt.internal.cocoa.NSColor;
25 import dwt.internal.cocoa.NSFont; 27 import dwt.internal.cocoa.NSFont;
26 import dwt.internal.cocoa.NSGradient; 28 import dwt.internal.cocoa.NSGradient;
27 import dwt.internal.cocoa.NSGraphicsContext; 29 import dwt.internal.cocoa.NSGraphicsContext;
28 import dwt.internal.cocoa.NSImage; 30 import dwt.internal.cocoa.NSImage;
29 import dwt.internal.cocoa.NSInteger; 31 import dwt.internal.cocoa.NSInteger;
30 import dwt.internal.cocoa.NSMutableDictionary; 32 import dwt.internal.cocoa.NSMutableDictionary;
33 import dwt.internal.cocoa.NSMutableParagraphStyle;
31 import dwt.internal.cocoa.NSPoint; 34 import dwt.internal.cocoa.NSPoint;
32 import dwt.internal.cocoa.NSRect; 35 import dwt.internal.cocoa.NSRect;
33 import dwt.internal.cocoa.NSSize; 36 import dwt.internal.cocoa.NSSize;
34 import dwt.internal.cocoa.NSString; 37 import dwt.internal.cocoa.NSString;
38 import dwt.internal.cocoa.NSThread;
39 import dwt.internal.cocoa.NSView;
35 import dwt.internal.cocoa.OS; 40 import dwt.internal.cocoa.OS;
36 41
37 import tango.text.convert.Format; 42 import tango.text.convert.Format;
38 43
39 import dwt.dwthelper.utils; 44 import dwt.dwthelper.utils;
83 * <p> 88 * <p>
84 * Note: Only one of LEFT_TO_RIGHT and RIGHT_TO_LEFT may be specified. 89 * Note: Only one of LEFT_TO_RIGHT and RIGHT_TO_LEFT may be specified.
85 * </p> 90 * </p>
86 * 91 *
87 * @see dwt.events.PaintEvent 92 * @see dwt.events.PaintEvent
93 * @see <a href="http://www.eclipse.org/swt/snippets/#gc">GC snippets</a>
94 * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Examples: GraphicsExample, PaintExample</a>
95 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
88 */ 96 */
89 public final class GC : Resource { 97 public final class GC : Resource {
90 98
91 alias Resource.init_ init_; 99 alias Resource.init_ init_;
92 100
228 gc.device = data.device; 236 gc.device = data.device;
229 gc.init_(drawable, data, context); 237 gc.init_(drawable, data, context);
230 return gc; 238 return gc;
231 } 239 }
232 240
233 /** 241 NSAutoreleasePool checkGC (int mask) {
234 * Invokes platform specific functionality to wrap a graphics context. 242 NSAutoreleasePool pool = null;
235 * <p> 243 if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
236 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public 244 if ((mask & (CLIPPING | TRANSFORM)) !is 0) {
237 * API for <code>GC</code>. It is marked public only so that it 245 NSGraphicsContext.setCurrentContext(handle);
238 * can be shared within the packages provided by DWT. It is not 246 NSView view = data.view;
239 * available on all platforms, and should never be called from 247 if (view !is null && data.paintRect is null) {
240 * application code. 248 NSRect rect = view.convertRect_toView_(view.bounds(), null);
241 * </p> 249 NSRect visibleRect = view.visibleRect();
242 * 250 if (data.windowRect is null || rect.x !is data.windowRect.x || rect.y !is data.windowRect.y ||
243 * @param context the Quartz context. 251 rect.width !is data.windowRect.width || rect.height !is data.windowRect.height ||
244 * @param data the data for the receiver. 252 visibleRect.x !is data.visibleRect.x || visibleRect.y !is data.visibleRect.y ||
245 * 253 visibleRect.width !is data.visibleRect.width || visibleRect.height !is data.visibleRect.height)
246 * @return a new <code>GC</code> 254 {
247 */ 255 data.state &= ~CLIPPING;
248 public static GC carbon_new(objc.id context, GCData data) { 256 data.windowRect = rect;
249 GC gc = new GC(); 257 data.visibleRect = visibleRect;
250 gc.device = data.device; 258 }
251 gc.init_(null, data, context); 259 }
252 return gc; 260 if ((data.state & CLIPPING) is 0 || (data.state & TRANSFORM) is 0) {
253 } 261 handle.restoreGraphicsState();
254 262 handle.saveGraphicsState();
255 void checkGC (int mask) { 263 if (view !is null && data.paintRect is null) {
256 if ((data.state & CLIPPING) is 0 || (data.state & TRANSFORM) is 0) { 264 NSAffineTransform transform = NSAffineTransform.transform();
257 handle.restoreGraphicsState(); 265 NSRect rect = data.windowRect;
258 handle.saveGraphicsState(); 266 transform.translateXBy(rect.x, rect.y + rect.height);
259 if (data.clipPath !is null) data.clipPath.addClip(); 267 transform.scaleXBy(1, -1);
260 if (data.transform !is null) data.transform.concat(); 268 transform.concat();
261 mask &= ~(TRANSFORM | CLIPPING); 269 NSBezierPath.bezierPathWithRect(data.visibleRect).addClip();
262 data.state |= TRANSFORM | CLIPPING; 270 }
263 data.state &= ~(BACKGROUND | FOREGROUND); 271 if (data.clipPath !is null) data.clipPath.addClip();
272 if (data.transform !is null) data.transform.concat();
273 mask &= ~(TRANSFORM | CLIPPING);
274 data.state |= TRANSFORM | CLIPPING;
275 data.state &= ~(BACKGROUND | FOREGROUND);
276 }
264 } 277 }
265 278
266 int state = data.state; 279 int state = data.state;
267 if ((state & mask) is mask) return; 280 if ((state & mask) is mask) return pool;
268 state = (state ^ mask) & mask; 281 state = (state ^ mask) & mask;
269 data.state |= mask; 282 data.state |= mask;
270 283
271 if ((state & FOREGROUND) !is 0) { 284 if ((state & FOREGROUND) !is 0) {
272 Pattern pattern = data.foregroundPattern; 285 Pattern pattern = data.foregroundPattern;
368 strokeWidth = data.lineWidth * scaling; 381 strokeWidth = data.lineWidth * scaling;
369 if (strokeWidth is 0 || (cast(size_t)strokeWidth % 2) is 1) { 382 if (strokeWidth is 0 || (cast(size_t)strokeWidth % 2) is 1) {
370 data.drawYOffset = 0.5f / scaling; 383 data.drawYOffset = 0.5f / scaling;
371 } 384 }
372 } 385 }
386 return pool;
373 } 387 }
374 388
375 /** 389 /**
376 * Copies a rectangular area of the receiver at the specified 390 * Copies a rectangular area of the receiver at the specified
377 * position into the image, which must be of type <code>DWT.BITMAP</code>. 391 * position into the image, which must be of type <code>DWT.BITMAP</code>.
644 658
645 NSAttributedString createString(String string, int flags) { 659 NSAttributedString createString(String string, int flags) {
646 NSMutableDictionary dict = NSMutableDictionary.dictionaryWithCapacity(4); 660 NSMutableDictionary dict = NSMutableDictionary.dictionaryWithCapacity(4);
647 CGFloat[] foreground = data.foreground; 661 CGFloat[] foreground = data.foreground;
648 NSColor color = NSColor.colorWithDeviceRed(foreground[0], foreground[1], foreground[2], data.alpha / 255f); 662 NSColor color = NSColor.colorWithDeviceRed(foreground[0], foreground[1], foreground[2], data.alpha / 255f);
649 dict.setObject(color, OS.NSForegroundColorAttributeName()); 663 dict.setObject(color, OS.NSForegroundColorAttributeName);
650 dict.setObject(data.font.handle, OS.NSFontAttributeName()); 664 dict.setObject(data.font.handle, OS.NSFontAttributeName);
651 if ((flags & DWT.DRAW_TRANSPARENT) is 0) { 665 if ((flags & DWT.DRAW_TRANSPARENT) is 0) {
652 CGFloat[] background = data.background; 666 CGFloat[] background = data.background;
653 color = NSColor.colorWithDeviceRed(background[0], background[1], background[2], data.alpha / 255f); 667 color = NSColor.colorWithDeviceRed(background[0], background[1], background[2], data.alpha / 255f);
654 dict.setObject(color, OS.FuncNSBackgroundColorAttributeName()); 668 dict.setObject(color, OS.FuncNSBackgroundColorAttributeName());
655 } 669 }
670 if ((flags & DWT.DRAW_TAB) is 0) {
671 NSMutableParagraphStyle paragraph = (NSMutableParagraphStyle)new NSMutableParagraphStyle().alloc().init();
672 paragraph.setAlignment(OS.NSLeftTextAlignment);
673 paragraph.setLineBreakMode(OS.NSLineBreakByClipping);
674 paragraph.setTabStops(NSArray.array());
675 dict.setObject(paragraph, OS.NSParagraphStyleAttributeName);
676 paragraph.release();
677 }
656 size_t length = string.length(); 678 size_t length = string.length();
657 char[] chars = new char[length]; 679 char[] chars = new char[length];
658 string.getChars(0, length, chars, 0); 680 string.getChars(0, length, chars, 0);
659 // int breakCount = 0; 681 int breakCount = 0;
660 // int[] breaks = null; 682 int[] breaks = null;
661 // if ((flags & (DWT.DRAW_MNEMONIC | DWT.DRAW_DELIMITER)) !is 0) { 683 if ((flags & DWT.DRAW_MNEMONIC) !is 0 || (flags & DWT.DRAW_DELIMITER) is 0) {
662 // int i=0, j=0; 684 int i=0, j=0;
663 // while (i < chars.length) { 685 while (i < chars.length) {
664 // char c = chars [j++] = chars [i++]; 686 char c = chars [j++] = chars [i++];
665 // switch (c) { 687 switch (c) {
666 // case '&': { 688 case '&': {
667 // if ((flags & DWT.DRAW_MNEMONIC) !is 0) { 689 if ((flags & DWT.DRAW_MNEMONIC) !is 0) {
668 // if (i is chars.length) {continue;} 690 if (i is chars.length) {continue;}
669 // if (chars [i] is '&') {i++; continue;} 691 if (chars [i] is '&') {i++; continue;}
670 // j--; 692 j--;
671 // } 693 }
672 // break; 694 break;
673 // } 695 }
674 // case '\r': 696 case '\r':
675 // case '\n': { 697 case '\n': {
676 // if ((flags & DWT.DRAW_DELIMITER) !is 0) { 698 if ((flags & DWT.DRAW_DELIMITER) is 0) {
677 // if (c is '\r' && i !is chars.length && chars[i] is '\n') i++; 699 if (c is '\r' && i !is chars.length && chars[i] is '\n') i++;
678 // j--; 700 j--;
679 // if (breaks is null) { 701 if (breaks is null) {
680 // breaks = new int[4]; 702 breaks = new int[4];
681 // } else if (breakCount is breaks.length) { 703 } else if (breakCount is breaks.length) {
682 // int[] newBreaks = new int[breaks.length + 4]; 704 int[] newBreaks = new int[breaks.length + 4];
683 // System.arraycopy(breaks, 0, newBreaks, 0, breaks.length); 705 System.arraycopy(breaks, 0, newBreaks, 0, breaks.length);
684 // breaks = newBreaks; 706 breaks = newBreaks;
685 // } 707 }
686 // breaks[breakCount++] = j; 708 breaks[breakCount++] = j;
687 // } 709 }
688 // break; 710 break;
689 // } 711 }
690 // } 712 }
691 // } 713 }
692 // length = j; 714 length = j;
693 // } 715 }
694 NSString str = NSString.stringWithCharacters(chars.toCharArray().ptr, length); 716 NSString str = NSString.stringWithCharacters(chars.toCharArray().ptr, length);
695 return (cast(NSAttributedString)(new NSAttributedString()).alloc()).initWithString_attributes_(str, dict); 717 return (cast(NSAttributedString)(new NSAttributedString()).alloc()).initWithString(str, dict);
696 } 718 }
697 719
698 void destroy() { 720 void destroy() {
699 /* Free resources */ 721 /* Free resources */
700 Image image = data.image; 722 Image image = data.image;
701 if (image !is null) { 723 if (image !is null) {
702 image.memGC = null; 724 image.memGC = null;
703 image.createAlpha(); 725 image.createAlpha();
704 } 726 }
727 if (data.path !is null) data.path.release();
705 if (data.clipPath !is null) data.clipPath.release(); 728 if (data.clipPath !is null) data.clipPath.release();
706 if (data.transform !is null) data.transform.release(); 729 if (data.transform !is null) data.transform.release();
707 if (data.inverseTransform !is null) data.inverseTransform.release(); 730 if (data.inverseTransform !is null) data.inverseTransform.release();
708 data.path = data.clipPath = null; 731 data.path = data.clipPath = null;
709 data.transform = data.inverseTransform = null; 732 data.transform = data.inverseTransform = null;
748 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 771 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
749 * </ul> 772 * </ul>
750 */ 773 */
751 public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) { 774 public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
752 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 775 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
753 NSGraphicsContext context = NSGraphicsContext.currentContext();
754 NSGraphicsContext.setCurrentContext(handle);
755 checkGC(DRAW);
756 if (width < 0) { 776 if (width < 0) {
757 x = x + width; 777 x = x + width;
758 width = -width; 778 width = -width;
759 } 779 }
760 if (height < 0) { 780 if (height < 0) {
761 y = y + height; 781 y = y + height;
762 height = -height; 782 height = -height;
763 } 783 }
764 if (width is 0 || height is 0 || arcAngle is 0) return; 784 if (width is 0 || height is 0 || arcAngle is 0) return;
765 handle.saveGraphicsState(); 785 NSAutoreleasePool pool = checkGC(DRAW);
766 NSAffineTransform transform = NSAffineTransform.transform(); 786 try {
787 handle.saveGraphicsState();
788 NSAffineTransform transform = NSAffineTransform.transform();
767 CGFloat xOffset = data.drawXOffset, yOffset = data.drawYOffset; 789 CGFloat xOffset = data.drawXOffset, yOffset = data.drawYOffset;
768 transform.translateXBy(x + xOffset + width / 2f, y + yOffset + height / 2f); 790 transform.translateXBy(x + xOffset + width / 2f, y + yOffset + height / 2f);
769 transform.scaleXBy(width / 2f, height / 2f); 791 transform.scaleXBy(width / 2f, height / 2f);
770 NSBezierPath path = data.path; 792 NSBezierPath path = data.path;
771 NSPoint center = NSPoint(); 793 NSPoint center = NSPoint();
772 CGFloat sAngle = -startAngle; 794 CGFloat sAngle = -startAngle;
773 CGFloat eAngle = -(startAngle + arcAngle); 795 CGFloat eAngle = -(startAngle + arcAngle);
774 path.appendBezierPathWithArcWithCenter_radius_startAngle_endAngle_clockwise_(center, 1, sAngle, eAngle, arcAngle>0); 796 path.appendBezierPathWithArcWithCenter(center, 1, sAngle, eAngle, arcAngle>0);
775 path.transformUsingAffineTransform(transform); 797 path.transformUsingAffineTransform(transform);
776 path.stroke(); 798 path.stroke();
777 path.removeAllPoints(); 799 path.removeAllPoints();
778 handle.restoreGraphicsState(); 800 handle.restoreGraphicsState();
779 NSGraphicsContext.setCurrentContext(context); 801 } finally {
802 uncheckGC(pool);
803 }
780 } 804 }
781 805
782 /** 806 /**
783 * Draws a rectangle, based on the specified arguments, which has 807 * Draws a rectangle, based on the specified arguments, which has
784 * the appearance of the platform's <em>focus rectangle</em> if the 808 * the appearance of the platform's <em>focus rectangle</em> if the
796 * 820 *
797 * @see #drawRectangle(int, int, int, int) 821 * @see #drawRectangle(int, int, int, int)
798 */ 822 */
799 public void drawFocus(int x, int y, int width, int height) { 823 public void drawFocus(int x, int y, int width, int height) {
800 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 824 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
801 NSGraphicsContext context = NSGraphicsContext.currentContext(); 825 NSAutoreleasePool pool = checkGC(CLIPPING | TRANSFORM);
802 NSGraphicsContext.setCurrentContext(handle); 826 try {
803 checkGC(CLIPPING | TRANSFORM); 827 // int[] metric = new int[1];
804 // int[] metric = new int[1]; 828 // OS.GetThemeMetric(OS.kThemeMetricFocusRectOutset, metric);
805 // OS.GetThemeMetric(OS.kThemeMetricFocusRectOutset, metric); 829 // CGRect rect = new CGRect ();
806 // CGRect rect = new CGRect (); 830 // rect.x = x + metric[0];
807 // rect.x = x + metric[0]; 831 // rect.y = y + metric[0];
808 // rect.y = y + metric[0]; 832 // rect.width = width - metric[0] * 2;
809 // rect.width = width - metric[0] * 2; 833 // rect.height = height - metric[0] * 2;
810 // rect.height = height - metric[0] * 2; 834 // OS.HIThemeDrawFocusRect(rect, true, handle, OS.kHIThemeOrientationNormal);
811 // OS.HIThemeDrawFocusRect(rect, true, handle, OS.kHIThemeOrientationNormal); 835 } finally {
812 // flush(); 836 uncheckGC(pool);
813 NSGraphicsContext.setCurrentContext(context); 837 }
814 } 838 }
815 839
816 /** 840 /**
817 * Draws the given image in the receiver at the specified 841 * Draws the given image in the receiver at the specified
818 * coordinates. 842 * coordinates.
881 if (image.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); 905 if (image.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
882 drawImage(image, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, false); 906 drawImage(image, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, false);
883 } 907 }
884 908
885 void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, bool simple) { 909 void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, bool simple) {
886 NSGraphicsContext context = NSGraphicsContext.currentContext();
887 NSGraphicsContext.setCurrentContext(handle);
888 checkGC(CLIPPING | TRANSFORM);
889 NSImage imageHandle = srcImage.handle; 910 NSImage imageHandle = srcImage.handle;
890 NSSize size = imageHandle.size(); 911 NSSize size = imageHandle.size();
891 int imgWidth = cast(int)size.width; 912 int imgWidth = cast(int)size.width;
892 int imgHeight = cast(int)size.height; 913 int imgHeight = cast(int)size.height;
893 if (simple) { 914 if (simple) {
896 } else { 917 } else {
897 simple = srcX is 0 && srcY is 0 && 918 simple = srcX is 0 && srcY is 0 &&
898 srcWidth is destWidth && destWidth is imgWidth && 919 srcWidth is destWidth && destWidth is imgWidth &&
899 srcHeight is destHeight && destHeight is imgHeight; 920 srcHeight is destHeight && destHeight is imgHeight;
900 if (srcX + srcWidth > imgWidth || srcY + srcHeight > imgHeight) { 921 if (srcX + srcWidth > imgWidth || srcY + srcHeight > imgHeight) {
901 NSGraphicsContext.setCurrentContext(context);
902 DWT.error(DWT.ERROR_INVALID_ARGUMENT); 922 DWT.error(DWT.ERROR_INVALID_ARGUMENT);
903 } 923 }
904 } 924 }
905 if (srcImage.memGC !is null) srcImage.createAlpha(); 925 NSAutoreleasePool pool = checkGC(CLIPPING | TRANSFORM);
906 handle.saveGraphicsState(); 926 try {
907 NSAffineTransform transform = NSAffineTransform.transform(); 927 if (srcImage.memGC !is null) {
908 transform.scaleXBy(1, -1); 928 srcImage.createAlpha();
909 transform.translateXBy(0, -(destHeight + 2 * destY)); 929 }
910 transform.concat(); 930 handle.saveGraphicsState();
931 NSAffineTransform transform = NSAffineTransform.transform();
932 transform.scaleXBy(1, -1);
933 transform.translateXBy(0, -(destHeight + 2 * destY));
934 transform.concat();
911 NSRect srcRect = NSRect(); 935 NSRect srcRect = NSRect();
912 srcRect.x = srcX; 936 srcRect.x = srcX;
913 srcRect.y = srcY; 937 srcRect.y = imgHeight - (srcY + srcHeight);
914 srcRect.width = srcWidth; 938 srcRect.width = srcWidth;
915 srcRect.height = srcHeight; 939 srcRect.height = srcHeight;
916 NSRect destRect = NSRect(); 940 NSRect destRect = NSRect();
917 destRect.x = destX; 941 destRect.x = destX;
918 destRect.y = destY; 942 destRect.y = destY;
919 destRect.width = destWidth; 943 destRect.width = destWidth;
920 destRect.height = destHeight; 944 destRect.height = destHeight;
921 imageHandle.drawInRect(destRect, srcRect, NSCompositeSourceOver, 1); 945 imageHandle.drawInRect(destRect, srcRect, NSCompositeSourceOver, 1);
922 handle.restoreGraphicsState(); 946 handle.restoreGraphicsState();
923 NSGraphicsContext.setCurrentContext(context); 947 } finally {
948 uncheckGC(pool);
949 }
924 } 950 }
925 951
926 /** 952 /**
927 * Draws a line, using the foreground color, between the points 953 * Draws a line, using the foreground color, between the points
928 * (<code>x1</code>, <code>y1</code>) and (<code>x2</code>, <code>y2</code>). 954 * (<code>x1</code>, <code>y1</code>) and (<code>x2</code>, <code>y2</code>).
936 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 962 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
937 * </ul> 963 * </ul>
938 */ 964 */
939 public void drawLine(int x1, int y1, int x2, int y2) { 965 public void drawLine(int x1, int y1, int x2, int y2) {
940 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 966 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
941 NSGraphicsContext context = NSGraphicsContext.currentContext(); 967 NSAutoreleasePool pool = checkGC(DRAW);
942 NSGraphicsContext.setCurrentContext(handle); 968 try {
943 checkGC(DRAW); 969 NSBezierPath path = data.path;
944 NSBezierPath path = data.path;
945 NSPoint pt = NSPoint(); 970 NSPoint pt = NSPoint();
946 pt.x = x1 + data.drawXOffset; 971 pt.x = x1 + data.drawXOffset;
947 pt.y = y1 + data.drawYOffset; 972 pt.y = y1 + data.drawYOffset;
948 path.moveToPoint(pt); 973 path.moveToPoint(pt);
949 pt.x = x2 + data.drawXOffset; 974 pt.x = x2 + data.drawXOffset;
950 pt.y = y2 + data.drawYOffset; 975 pt.y = y2 + data.drawYOffset;
951 path.lineToPoint(pt); 976 path.lineToPoint(pt);
952 path.stroke(); 977 path.stroke();
953 path.removeAllPoints(); 978 path.removeAllPoints();
954 NSGraphicsContext.setCurrentContext(context); 979 } finally {
980 uncheckGC(pool);
981 }
955 } 982 }
956 983
957 /** 984 /**
958 * Draws the outline of an oval, using the foreground color, 985 * Draws the outline of an oval, using the foreground color,
959 * within the specified rectangular area. 986 * within the specified rectangular area.
975 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 1002 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
976 * </ul> 1003 * </ul>
977 */ 1004 */
978 public void drawOval(int x, int y, int width, int height) { 1005 public void drawOval(int x, int y, int width, int height) {
979 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 1006 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
980 NSGraphicsContext context = NSGraphicsContext.currentContext(); 1007 NSAutoreleasePool pool = checkGC(DRAW);
981 NSGraphicsContext.setCurrentContext(handle); 1008 try {
982 checkGC(DRAW); 1009 if (width < 0) {
983 if (width < 0) { 1010 x = x + width;
984 x = x + width; 1011 width = -width;
985 width = -width; 1012 }
986 } 1013 if (height < 0) {
987 if (height < 0) { 1014 y = y + height;
988 y = y + height; 1015 height = -height;
989 height = -height; 1016 }
990 } 1017 NSBezierPath path = data.path;
991 NSBezierPath path = data.path;
992 NSRect rect = NSRect(); 1018 NSRect rect = NSRect();
993 rect.x = x + data.drawXOffset; 1019 rect.x = x + data.drawXOffset;
994 rect.y = y + data.drawXOffset; 1020 rect.y = y + data.drawXOffset;
995 rect.width = width; 1021 rect.width = width;
996 rect.height = height; 1022 rect.height = height;
997 path.appendBezierPathWithOvalInRect(rect); 1023 path.appendBezierPathWithOvalInRect(rect);
998 path.stroke(); 1024 path.stroke();
999 path.removeAllPoints(); 1025 path.removeAllPoints();
1000 NSGraphicsContext.setCurrentContext(context); 1026 } finally {
1027 uncheckGC(pool);
1028 }
1001 } 1029 }
1002 1030
1003 /** 1031 /**
1004 * Draws the path described by the parameter. 1032 * Draws the path described by the parameter.
1005 * <p> 1033 * <p>
1025 */ 1053 */
1026 public void drawPath(Path path) { 1054 public void drawPath(Path path) {
1027 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 1055 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
1028 if (path is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); 1056 if (path is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
1029 if (path.handle is null) DWT.error(DWT.ERROR_INVALID_ARGUMENT); 1057 if (path.handle is null) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
1030 NSGraphicsContext context = NSGraphicsContext.currentContext(); 1058 NSAutoreleasePool pool = checkGC(DRAW);
1031 NSGraphicsContext.setCurrentContext(handle); 1059 try {
1032 checkGC(DRAW); 1060 handle.saveGraphicsState();
1033 handle.saveGraphicsState(); 1061 NSAffineTransform transform = NSAffineTransform.transform();
1034 NSAffineTransform transform = NSAffineTransform.transform(); 1062 transform.translateXBy(data.drawXOffset, data.drawYOffset);
1035 transform.translateXBy(data.drawXOffset, data.drawYOffset); 1063 transform.concat();
1036 transform.concat(); 1064 NSBezierPath drawPath = data.path;
1037 NSBezierPath drawPath = data.path; 1065 drawPath.appendBezierPath(path.handle);
1038 drawPath.appendBezierPath(path.handle); 1066 drawPath.stroke();
1039 drawPath.stroke(); 1067 drawPath.removeAllPoints();
1040 drawPath.removeAllPoints(); 1068 handle.restoreGraphicsState();
1041 handle.restoreGraphicsState(); 1069 } finally {
1042 NSGraphicsContext.setCurrentContext(context); 1070 uncheckGC(pool);
1071 }
1043 } 1072 }
1044 1073
1045 /** 1074 /**
1046 * Draws a pixel, using the foreground color, at the specified 1075 * Draws a pixel, using the foreground color, at the specified
1047 * point (<code>x</code>, <code>y</code>). 1076 * point (<code>x</code>, <code>y</code>).
1059 * 1088 *
1060 * @since 3.0 1089 * @since 3.0
1061 */ 1090 */
1062 public void drawPoint(int x, int y) { 1091 public void drawPoint(int x, int y) {
1063 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 1092 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
1064 NSGraphicsContext context = NSGraphicsContext.currentContext(); 1093 NSAutoreleasePool pool = checkGC(FOREGROUND_FILL | CLIPPING | TRANSFORM);
1065 NSGraphicsContext.setCurrentContext(handle); 1094 try {
1066 checkGC(FOREGROUND_FILL);
1067 NSRect rect = NSRect(); 1095 NSRect rect = NSRect();
1068 rect.x = x; 1096 rect.x = x;
1069 rect.y = y; 1097 rect.y = y;
1070 rect.width = 1; 1098 rect.width = 1;
1071 rect.height = 1; 1099 rect.height = 1;
1072 NSBezierPath path = data.path; 1100 NSBezierPath path = data.path;
1073 path.appendBezierPathWithRect(rect); 1101 path.appendBezierPathWithRect(rect);
1074 path.fill(); 1102 path.fill();
1075 path.removeAllPoints(); 1103 path.removeAllPoints();
1076 NSGraphicsContext.setCurrentContext(context); 1104 } finally {
1105 uncheckGC(pool);
1106 }
1077 } 1107 }
1078 1108
1079 /** 1109 /**
1080 * Draws the closed polygon which is defined by the specified array 1110 * Draws the closed polygon which is defined by the specified array
1081 * of integer coordinates, using the receiver's foreground color. The array 1111 * of integer coordinates, using the receiver's foreground color. The array
1094 * </ul> 1124 * </ul>
1095 */ 1125 */
1096 public void drawPolygon(int[] pointArray) { 1126 public void drawPolygon(int[] pointArray) {
1097 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 1127 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
1098 if (pointArray is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); 1128 if (pointArray is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
1099 NSGraphicsContext context = NSGraphicsContext.currentContext();
1100 NSGraphicsContext.setCurrentContext(handle);
1101 checkGC(DRAW);
1102 if (pointArray.length < 4) return; 1129 if (pointArray.length < 4) return;
1103 CGFloat xOffset = data.drawXOffset, yOffset = data.drawYOffset; 1130 NSAutoreleasePool pool = checkGC(DRAW);
1104 NSBezierPath path = data.path; 1131 try {
1132 float /*double*/ xOffset = data.drawXOffset, yOffset = data.drawYOffset;
1133 NSBezierPath path = data.path;
1105 NSPoint pt = NSPoint(); 1134 NSPoint pt = NSPoint();
1106 pt.x = pointArray[0] + xOffset; 1135 pt.x = pointArray[0] + xOffset;
1107 pt.y = pointArray[1] + yOffset; 1136 pt.y = pointArray[1] + yOffset;
1108 path.moveToPoint(pt); 1137 path.moveToPoint(pt);
1109 int end = pointArray.length / 2 * 2; 1138 int end = pointArray.length / 2 * 2;
1110 for (int i = 2; i < end; i+=2) { 1139 for (int i = 2; i < end; i+=2) {
1111 pt.x = pointArray[i] + xOffset; 1140 pt.x = pointArray[i] + xOffset;
1112 pt.y = pointArray[i+1] + yOffset; 1141 pt.y = pointArray[i+1] + yOffset;
1113 path.lineToPoint(pt); 1142 path.lineToPoint(pt);
1114 } 1143 }
1115 path.closePath(); 1144 path.closePath();
1116 path.stroke(); 1145 path.stroke();
1117 path.removeAllPoints(); 1146 path.removeAllPoints();
1118 NSGraphicsContext.setCurrentContext(context); 1147 } finally {
1148 uncheckGC(pool);
1149 }
1119 } 1150 }
1120 1151
1121 /** 1152 /**
1122 * Draws the polyline which is defined by the specified array 1153 * Draws the polyline which is defined by the specified array
1123 * of integer coordinates, using the receiver's foreground color. The array 1154 * of integer coordinates, using the receiver's foreground color. The array
1136 * </ul> 1167 * </ul>
1137 */ 1168 */
1138 public void drawPolyline(int[] pointArray) { 1169 public void drawPolyline(int[] pointArray) {
1139 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 1170 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
1140 if (pointArray is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); 1171 if (pointArray is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
1141 NSGraphicsContext context = NSGraphicsContext.currentContext();
1142 NSGraphicsContext.setCurrentContext(handle);
1143 checkGC(DRAW);
1144 if (pointArray.length < 4) return; 1172 if (pointArray.length < 4) return;
1145 CGFloat xOffset = data.drawXOffset, yOffset = data.drawYOffset; 1173 NSAutoreleasePool pool = checkGC(DRAW);
1146 NSBezierPath path = data.path; 1174 try {
1175 float /*double*/ xOffset = data.drawXOffset, yOffset = data.drawYOffset;
1176 NSBezierPath path = data.path;
1147 NSPoint pt = NSPoint(); 1177 NSPoint pt = NSPoint();
1148 pt.x = pointArray[0] + xOffset; 1178 pt.x = pointArray[0] + xOffset;
1149 pt.y = pointArray[1] + yOffset; 1179 pt.y = pointArray[1] + yOffset;
1150 path.moveToPoint(pt); 1180 path.moveToPoint(pt);
1151 int end = pointArray.length / 2 * 2; 1181 int end = pointArray.length / 2 * 2;
1152 for (int i = 2; i < end; i+=2) { 1182 for (int i = 2; i < end; i+=2) {
1153 pt.x = pointArray[i] + xOffset; 1183 pt.x = pointArray[i] + xOffset;
1154 pt.y = pointArray[i+1] + yOffset; 1184 pt.y = pointArray[i+1] + yOffset;
1155 path.lineToPoint(pt); 1185 path.lineToPoint(pt);
1156 } 1186 }
1157 path.stroke(); 1187 path.stroke();
1158 path.removeAllPoints(); 1188 path.removeAllPoints();
1159 NSGraphicsContext.setCurrentContext(context); 1189 } finally {
1190 uncheckGC(pool);
1191 }
1160 } 1192 }
1161 1193
1162 /** 1194 /**
1163 * Draws the outline of the rectangle specified by the arguments, 1195 * Draws the outline of the rectangle specified by the arguments,
1164 * using the receiver's foreground color. The left and right edges 1196 * using the receiver's foreground color. The left and right edges
1174 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 1206 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
1175 * </ul> 1207 * </ul>
1176 */ 1208 */
1177 public void drawRectangle(int x, int y, int width, int height) { 1209 public void drawRectangle(int x, int y, int width, int height) {
1178 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 1210 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
1179 NSGraphicsContext context = NSGraphicsContext.currentContext(); 1211 NSAutoreleasePool pool = checkGC(DRAW);
1180 NSGraphicsContext.setCurrentContext(handle); 1212 try {
1181 checkGC(DRAW); 1213 if (width < 0) {
1182 if (width < 0) { 1214 x = x + width;
1183 x = x + width; 1215 width = -width;
1184 width = -width; 1216 }
1185 } 1217 if (height < 0) {
1186 if (height < 0) { 1218 y = y + height;
1187 y = y + height; 1219 height = -height;
1188 height = -height; 1220 }
1189 }
1190 NSRect rect = NSRect(); 1221 NSRect rect = NSRect();
1191 rect.x = x + data.drawXOffset; 1222 rect.x = x + data.drawXOffset;
1192 rect.y = y + data.drawYOffset; 1223 rect.y = y + data.drawYOffset;
1193 rect.width = width; 1224 rect.width = width;
1194 rect.height = height; 1225 rect.height = height;
1195 NSBezierPath path = data.path; 1226 NSBezierPath path = data.path;
1196 path.appendBezierPathWithRect(rect); 1227 path.appendBezierPathWithRect(rect);
1197 path.stroke(); 1228 path.stroke();
1198 path.removeAllPoints(); 1229 path.removeAllPoints();
1199 NSGraphicsContext.setCurrentContext(context); 1230 } finally {
1231 uncheckGC(pool);
1232 }
1200 } 1233 }
1201 1234
1202 /** 1235 /**
1203 * Draws the outline of the specified rectangle, using the receiver's 1236 * Draws the outline of the specified rectangle, using the receiver's
1204 * foreground color. The left and right edges of the rectangle are at 1237 * foreground color. The left and right edges of the rectangle are at
1242 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 1275 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
1243 * </ul> 1276 * </ul>
1244 */ 1277 */
1245 public void drawRoundRectangle(int x, int y, int width, int height, int arcWidth, int arcHeight) { 1278 public void drawRoundRectangle(int x, int y, int width, int height, int arcWidth, int arcHeight) {
1246 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 1279 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
1247 NSGraphicsContext context = NSGraphicsContext.currentContext();
1248 NSGraphicsContext.setCurrentContext(handle);
1249 checkGC(DRAW);
1250 if (arcWidth is 0 || arcHeight is 0) { 1280 if (arcWidth is 0 || arcHeight is 0) {
1251 drawRectangle(x, y, width, height); 1281 drawRectangle(x, y, width, height);
1252 NSGraphicsContext.setCurrentContext(context);
1253 return; 1282 return;
1254 } 1283 }
1255 NSBezierPath path = data.path; 1284 NSAutoreleasePool pool = checkGC(DRAW);
1285 try {
1286 NSBezierPath path = data.path;
1256 NSRect rect = NSRect(); 1287 NSRect rect = NSRect();
1257 rect.x = x + data.drawXOffset; 1288 rect.x = x + data.drawXOffset;
1258 rect.y = y + data.drawYOffset; 1289 rect.y = y + data.drawYOffset;
1259 rect.width = width; 1290 rect.width = width;
1260 rect.height = height; 1291 rect.height = height;
1261 path.appendBezierPathWithRoundedRect(rect, arcWidth, arcHeight); 1292 path.appendBezierPathWithRoundedRect(rect, arcWidth, arcHeight);
1262 path.stroke(); 1293 path.stroke();
1263 path.removeAllPoints(); 1294 path.removeAllPoints();
1264 NSGraphicsContext.setCurrentContext(context); 1295 } finally {
1296 uncheckGC(pool);
1297 }
1265 } 1298 }
1266 1299
1267 /** 1300 /**
1268 * Draws the given string, using the receiver's current font and 1301 * Draws the given string, using the receiver's current font and
1269 * foreground color. No tab expansion or carriage return processing 1302 * foreground color. No tab expansion or carriage return processing
1393 * </ul> 1426 * </ul>
1394 */ 1427 */
1395 public void drawText (String string, int x, int y, int flags) { 1428 public void drawText (String string, int x, int y, int flags) {
1396 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 1429 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
1397 if (string is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); 1430 if (string is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
1398 NSGraphicsContext context = NSGraphicsContext.currentContext(); 1431 NSAutoreleasePool pool = checkGC(CLIPPING | TRANSFORM | FONT | FOREGROUND_FILL);
1399 NSGraphicsContext.setCurrentContext(handle); 1432 try {
1400 checkGC(CLIPPING | TRANSFORM | FONT | FOREGROUND_FILL); 1433 NSAttributedString str = createString(string, flags);
1401 NSAttributedString str = createString(string, flags); 1434 if (data.paintRect is null) {
1402 if (data.paintRect is null) { 1435 handle.saveGraphicsState();
1403 handle.saveGraphicsState(); 1436 NSAffineTransform transform = NSAffineTransform.transform();
1404 NSAffineTransform transform = NSAffineTransform.transform(); 1437 transform.scaleXBy(1, -1);
1405 transform.scaleXBy(1, -1); 1438 transform.translateXBy(0, -(str.size().height + 2 * y));
1406 transform.translateXBy(0, -(str.size().height + 2 * y)); 1439 transform.concat();
1407 transform.concat(); 1440 }
1408 }
1409 NSPoint pt = NSPoint(); 1441 NSPoint pt = NSPoint();
1410 pt.x = x; 1442 pt.x = x;
1411 pt.y = y; 1443 pt.y = y;
1412 str.drawAtPoint(pt); 1444 str.drawAtPoint(pt);
1413 str.release(); 1445 str.release();
1414 if (data.paintRect is null) { 1446 if (data.paintRect is null) {
1415 handle.restoreGraphicsState(); 1447 handle.restoreGraphicsState();
1416 } 1448 }
1417 NSGraphicsContext.setCurrentContext(context); 1449 } finally {
1450 uncheckGC(pool);
1451 }
1418 } 1452 }
1419 1453
1420 /** 1454 /**
1421 * Compares the argument to the receiver, and returns true 1455 * Compares the argument to the receiver, and returns true
1422 * if they represent the <em>same</em> object using a class 1456 * if they represent the <em>same</em> object using a class
1467 * 1501 *
1468 * @see #drawArc 1502 * @see #drawArc
1469 */ 1503 */
1470 public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) { 1504 public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
1471 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 1505 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
1472 NSGraphicsContext context = NSGraphicsContext.currentContext();
1473 NSGraphicsContext.setCurrentContext(handle);
1474 checkGC(FILL);
1475 if (width < 0) { 1506 if (width < 0) {
1476 x = x + width; 1507 x = x + width;
1477 width = -width; 1508 width = -width;
1478 } 1509 }
1479 if (height < 0) { 1510 if (height < 0) {
1480 y = y + height; 1511 y = y + height;
1481 height = -height; 1512 height = -height;
1482 } 1513 }
1483 if (width is 0 || height is 0 || arcAngle is 0) return; 1514 if (width is 0 || height is 0 || arcAngle is 0) return;
1484 handle.saveGraphicsState(); 1515 NSAutoreleasePool pool = checkGC(FILL);
1485 NSAffineTransform transform = NSAffineTransform.transform(); 1516 try {
1517 handle.saveGraphicsState();
1518 NSAffineTransform transform = NSAffineTransform.transform();
1486 CGFloat xOffset = data.drawXOffset, yOffset = data.drawYOffset; 1519 CGFloat xOffset = data.drawXOffset, yOffset = data.drawYOffset;
1487 transform.translateXBy(x + xOffset + width / 2f, y + yOffset + height / 2f); 1520 transform.translateXBy(x + xOffset + width / 2f, y + yOffset + height / 2f);
1488 transform.scaleXBy(width / 2f, height / 2f); 1521 transform.scaleXBy(width / 2f, height / 2f);
1489 NSBezierPath path = data.path; 1522 NSBezierPath path = data.path;
1490 NSPoint center = NSPoint(); 1523 NSPoint center = NSPoint();
1491 path.moveToPoint(center); 1524 path.moveToPoint(center);
1492 CGFloat sAngle = -startAngle; 1525 CGFloat sAngle = -startAngle;
1493 CGFloat eAngle = -(startAngle + arcAngle); 1526 CGFloat eAngle = -(startAngle + arcAngle);
1494 path.appendBezierPathWithArcWithCenter_radius_startAngle_endAngle_clockwise_(center, 1, sAngle, eAngle, arcAngle>0); 1527 path.appendBezierPathWithArcWithCenter(center, 1, sAngle, eAngle, arcAngle>0);
1495 path.closePath(); 1528 path.closePath();
1496 path.transformUsingAffineTransform(transform); 1529 path.transformUsingAffineTransform(transform);
1497 path.fill(); 1530 path.fill();
1498 path.removeAllPoints(); 1531 path.removeAllPoints();
1499 handle.restoreGraphicsState(); 1532 handle.restoreGraphicsState();
1500 NSGraphicsContext.setCurrentContext(context); 1533 } finally {
1534 uncheckGC(pool);
1535 }
1501 } 1536 }
1502 1537
1503 /** 1538 /**
1504 * Fills the interior of the specified rectangle with a gradient 1539 * Fills the interior of the specified rectangle with a gradient
1505 * sweeping from left to right or top to bottom progressing 1540 * sweeping from left to right or top to bottom progressing
1520 * 1555 *
1521 * @see #drawRectangle(int, int, int, int) 1556 * @see #drawRectangle(int, int, int, int)
1522 */ 1557 */
1523 public void fillGradientRectangle(int x, int y, int width, int height, bool vertical) { 1558 public void fillGradientRectangle(int x, int y, int width, int height, bool vertical) {
1524 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 1559 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
1525 NSGraphicsContext context = NSGraphicsContext.currentContext();
1526 NSGraphicsContext.setCurrentContext(handle);
1527 checkGC(CLIPPING | TRANSFORM);
1528 if ((width is 0) || (height is 0)) return; 1560 if ((width is 0) || (height is 0)) return;
1529 1561 NSAutoreleasePool pool = checkGC(CLIPPING | TRANSFORM);
1530 RGB backgroundRGB, foregroundRGB; 1562 try {
1531 backgroundRGB = getBackground().getRGB(); 1563 RGB backgroundRGB, foregroundRGB;
1532 foregroundRGB = getForeground().getRGB(); 1564 backgroundRGB = getBackground().getRGB();
1533 1565 foregroundRGB = getForeground().getRGB();
1534 RGB fromRGB, toRGB; 1566
1535 fromRGB = foregroundRGB; 1567 RGB fromRGB, toRGB;
1536 toRGB = backgroundRGB; 1568 fromRGB = foregroundRGB;
1537 bool swapColors = false; 1569 toRGB = backgroundRGB;
1538 if (width < 0) { 1570 bool swapColors = false;
1539 x += width; width = -width; 1571 if (width < 0) {
1540 if (! vertical) swapColors = true; 1572 x += width; width = -width;
1541 } 1573 if (! vertical) swapColors = true;
1542 if (height < 0) { 1574 }
1543 y += height; height = -height; 1575 if (height < 0) {
1544 if (vertical) swapColors = true; 1576 y += height; height = -height;
1545 } 1577 if (vertical) swapColors = true;
1546 if (swapColors) { 1578 }
1547 fromRGB = backgroundRGB; 1579 if (swapColors) {
1548 toRGB = foregroundRGB; 1580 fromRGB = backgroundRGB;
1549 } 1581 toRGB = foregroundRGB;
1550 if (fromRGB.equals(toRGB)) { 1582 }
1551 fillRectangle(x, y, width, height); 1583 if (fromRGB.equals(toRGB)) {
1552 } else { 1584 fillRectangle(x, y, width, height);
1553 NSColor startingColor = NSColor.colorWithDeviceRed(fromRGB.red / 255f, fromRGB.green / 255f, fromRGB.blue / 255f, data.alpha / 255f); 1585 } else {
1554 NSColor endingColor = NSColor.colorWithDeviceRed(toRGB.red / 255f, toRGB.green / 255f, toRGB.blue / 255f, data.alpha / 255f); 1586 NSColor startingColor = NSColor.colorWithDeviceRed(fromRGB.red / 255f, fromRGB.green / 255f, fromRGB.blue / 255f, data.alpha / 255f);
1587 NSColor endingColor = NSColor.colorWithDeviceRed(toRGB.red / 255f, toRGB.green / 255f, toRGB.blue / 255f, data.alpha / 255f);
1555 NSGradient gradient = (cast(NSGradient)(new NSGradient()).alloc()).initWithStartingColor(startingColor, endingColor); 1588 NSGradient gradient = (cast(NSGradient)(new NSGradient()).alloc()).initWithStartingColor(startingColor, endingColor);
1556 NSRect rect = NSRect(); 1589 NSRect rect = NSRect();
1590 rect.x = x;
1591 rect.y = y;
1592 rect.width = width;
1593 rect.height = height;
1594 gradient.drawInRect(rect, vertical ? 90 : 0);
1595 gradient.release();
1596 }
1597 } finally {
1598 uncheckGC(pool);
1599 }
1600 }
1601
1602 /**
1603 * Fills the interior of an oval, within the specified
1604 * rectangular area, with the receiver's background
1605 * color.
1606 *
1607 * @param x the x coordinate of the upper left corner of the oval to be filled
1608 * @param y the y coordinate of the upper left corner of the oval to be filled
1609 * @param width the width of the oval to be filled
1610 * @param height the height of the oval to be filled
1611 *
1612 * @exception DWTException <ul>
1613 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
1614 * </ul>
1615 *
1616 * @see #drawOval
1617 */
1618 public void fillOval(int x, int y, int width, int height) {
1619 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
1620 NSAutoreleasePool pool = checkGC(FILL);
1621 try {
1622 if (width < 0) {
1623 x = x + width;
1624 width = -width;
1625 }
1626 if (height < 0) {
1627 y = y + height;
1628 height = -height;
1629 }
1630 NSBezierPath path = data.path;
1631 NSRect rect = NSRect();
1557 rect.x = x; 1632 rect.x = x;
1558 rect.y = y; 1633 rect.y = y;
1559 rect.width = width; 1634 rect.width = width;
1560 rect.height = height; 1635 rect.height = height;
1561 gradient.drawInRect_angle_(rect, vertical ? 90 : 0); 1636 path.appendBezierPathWithOvalInRect(rect);
1562 gradient.release(); 1637 Pattern pattern = data.backgroundPattern;
1563 } 1638 if (pattern !is null && pattern.gradient !is null) {
1564 NSGraphicsContext.setCurrentContext(context); 1639 fillPattern(path, pattern);
1565 } 1640 } else {
1566 1641 path.fill();
1567 /** 1642 }
1568 * Fills the interior of an oval, within the specified 1643 path.removeAllPoints();
1569 * rectangular area, with the receiver's background 1644 } finally {
1570 * color. 1645 uncheckGC(pool);
1571 * 1646 }
1572 * @param x the x coordinate of the upper left corner of the oval to be filled
1573 * @param y the y coordinate of the upper left corner of the oval to be filled
1574 * @param width the width of the oval to be filled
1575 * @param height the height of the oval to be filled
1576 *
1577 * @exception DWTException <ul>
1578 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
1579 * </ul>
1580 *
1581 * @see #drawOval
1582 */
1583 public void fillOval(int x, int y, int width, int height) {
1584 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
1585 NSGraphicsContext context = NSGraphicsContext.currentContext();
1586 NSGraphicsContext.setCurrentContext(handle);
1587 checkGC(FILL);
1588 if (width < 0) {
1589 x = x + width;
1590 width = -width;
1591 }
1592 if (height < 0) {
1593 y = y + height;
1594 height = -height;
1595 }
1596 NSBezierPath path = data.path;
1597 NSRect rect = NSRect();
1598 rect.x = x;
1599 rect.y = y;
1600 rect.width = width;
1601 rect.height = height;
1602 path.appendBezierPathWithOvalInRect(rect);
1603 Pattern pattern = data.backgroundPattern;
1604 if (pattern !is null && pattern.gradient !is null) {
1605 fillPattern(path, pattern);
1606 } else {
1607 path.fill();
1608 }
1609 path.removeAllPoints();
1610 NSGraphicsContext.setCurrentContext(context);
1611 } 1647 }
1612 1648
1613 void fillPattern(NSBezierPath path, Pattern pattern) { 1649 void fillPattern(NSBezierPath path, Pattern pattern) {
1614 NSGraphicsContext context = NSGraphicsContext.currentContext(); 1650 handle.saveGraphicsState();
1615 NSGraphicsContext.setCurrentContext(handle);
1616 path.addClip(); 1651 path.addClip();
1617 pattern.gradient.drawFromPoint(pattern.pt1, pattern.pt2, OS.NSGradientDrawsAfterEndingLocation | OS.NSGradientDrawsBeforeStartingLocation); 1652 pattern.gradient.drawFromPoint(pattern.pt1, pattern.pt2, OS.NSGradientDrawsAfterEndingLocation | OS.NSGradientDrawsBeforeStartingLocation);
1618 NSGraphicsContext.setCurrentContext(context); 1653 handle.restoreGraphicsState();
1619 } 1654 }
1620 1655
1621 /** 1656 /**
1622 * Fills the path described by the parameter. 1657 * Fills the path described by the parameter.
1623 * <p> 1658 * <p>
1643 */ 1678 */
1644 public void fillPath(Path path) { 1679 public void fillPath(Path path) {
1645 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 1680 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
1646 if (path is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); 1681 if (path is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
1647 if (path.handle is null) DWT.error(DWT.ERROR_INVALID_ARGUMENT); 1682 if (path.handle is null) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
1648 NSGraphicsContext context = NSGraphicsContext.currentContext(); 1683 NSAutoreleasePool pool = checkGC(FILL);
1649 NSGraphicsContext.setCurrentContext(handle); 1684 try {
1650 checkGC(FILL); 1685 NSBezierPath drawPath = data.path;
1651 NSBezierPath drawPath = data.path; 1686 drawPath.appendBezierPath(path.handle);
1652 drawPath.appendBezierPath(path.handle); 1687 Pattern pattern = data.backgroundPattern;
1653 Pattern pattern = data.backgroundPattern; 1688 if (pattern !is null && pattern.gradient !is null) {
1654 if (pattern !is null && pattern.gradient !is null) { 1689 fillPattern(drawPath, pattern);
1655 fillPattern(drawPath, pattern); 1690 } else {
1656 } else { 1691 drawPath.fill();
1657 drawPath.fill(); 1692 }
1658 } 1693 drawPath.removeAllPoints();
1659 drawPath.removeAllPoints(); 1694 } finally {
1660 NSGraphicsContext.setCurrentContext(context); 1695 uncheckGC(pool);
1696 }
1661 } 1697 }
1662 1698
1663 /** 1699 /**
1664 * Fills the interior of the closed polygon which is defined by the 1700 * Fills the interior of the closed polygon which is defined by the
1665 * specified array of integer coordinates, using the receiver's 1701 * specified array of integer coordinates, using the receiver's
1680 * @see #drawPolygon 1716 * @see #drawPolygon
1681 */ 1717 */
1682 public void fillPolygon(int[] pointArray) { 1718 public void fillPolygon(int[] pointArray) {
1683 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 1719 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
1684 if (pointArray is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); 1720 if (pointArray is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
1685 NSGraphicsContext context = NSGraphicsContext.currentContext();
1686 NSGraphicsContext.setCurrentContext(handle);
1687 checkGC(FILL);
1688 if (pointArray.length < 4) return; 1721 if (pointArray.length < 4) return;
1689 NSBezierPath path = data.path; 1722 NSAutoreleasePool pool = checkGC(FILL);
1723 try {
1724 NSBezierPath path = data.path;
1690 NSPoint pt = NSPoint(); 1725 NSPoint pt = NSPoint();
1691 pt.x = pointArray[0]; 1726 pt.x = pointArray[0];
1692 pt.y = pointArray[1]; 1727 pt.y = pointArray[1];
1693 path.moveToPoint(pt); 1728 path.moveToPoint(pt);
1694 int end = pointArray.length / 2 * 2; 1729 int end = pointArray.length / 2 * 2;
1695 for (int i = 2; i < end; i+=2) { 1730 for (int i = 2; i < end; i+=2) {
1696 pt.x = pointArray[i]; 1731 pt.x = pointArray[i];
1697 pt.y = pointArray[i+1]; 1732 pt.y = pointArray[i+1];
1698 path.lineToPoint(pt); 1733 path.lineToPoint(pt);
1699 } 1734 }
1700 path.closePath(); 1735 path.closePath();
1701 Pattern pattern = data.backgroundPattern; 1736 Pattern pattern = data.backgroundPattern;
1702 if (pattern !is null && pattern.gradient !is null) { 1737 if (pattern !is null && pattern.gradient !is null) {
1703 fillPattern(path, pattern); 1738 fillPattern(path, pattern);
1704 } else { 1739 } else {
1705 path.fill(); 1740 path.fill();
1706 } 1741 }
1707 path.removeAllPoints(); 1742 path.removeAllPoints();
1708 NSGraphicsContext.setCurrentContext(context); 1743 } finally {
1744 uncheckGC(pool);
1745 }
1709 } 1746 }
1710 1747
1711 /** 1748 /**
1712 * Fills the interior of the rectangle specified by the arguments, 1749 * Fills the interior of the rectangle specified by the arguments,
1713 * using the receiver's background color. 1750 * using the receiver's background color.
1723 * 1760 *
1724 * @see #drawRectangle(int, int, int, int) 1761 * @see #drawRectangle(int, int, int, int)
1725 */ 1762 */
1726 public void fillRectangle(int x, int y, int width, int height) { 1763 public void fillRectangle(int x, int y, int width, int height) {
1727 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 1764 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
1728 NSGraphicsContext context = NSGraphicsContext.currentContext(); 1765 NSAutoreleasePool pool = checkGC(FILL);
1729 NSGraphicsContext.setCurrentContext(handle); 1766 try {
1730 checkGC(FILL); 1767 if (width < 0) {
1731 if (width < 0) { 1768 x = x + width;
1732 x = x + width; 1769 width = -width;
1733 width = -width; 1770 }
1734 } 1771 if (height < 0) {
1735 if (height < 0) { 1772 y = y + height;
1736 y = y + height; 1773 height = -height;
1737 height = -height; 1774 }
1738 }
1739 NSRect rect = NSRect(); 1775 NSRect rect = NSRect();
1740 rect.x = x; 1776 rect.x = x;
1741 rect.y = y; 1777 rect.y = y;
1742 rect.width = width; 1778 rect.width = width;
1743 rect.height = height; 1779 rect.height = height;
1744 NSBezierPath path = data.path; 1780 NSBezierPath path = data.path;
1745 path.appendBezierPathWithRect(rect); 1781 path.appendBezierPathWithRect(rect);
1746 Pattern pattern = data.backgroundPattern; 1782 Pattern pattern = data.backgroundPattern;
1747 if (pattern !is null && pattern.gradient !is null) { 1783 if (pattern !is null && pattern.gradient !is null) {
1748 fillPattern(path, pattern); 1784 fillPattern(path, pattern);
1749 } else { 1785 } else {
1750 path.fill(); 1786 path.fill();
1751 } 1787 }
1752 path.removeAllPoints(); 1788 path.removeAllPoints();
1753 NSGraphicsContext.setCurrentContext(context); 1789 } finally {
1790 uncheckGC(pool);
1791 }
1754 } 1792 }
1755 1793
1756 /** 1794 /**
1757 * Fills the interior of the specified rectangle, using the receiver's 1795 * Fills the interior of the specified rectangle, using the receiver's
1758 * background color. 1796 * background color.
1791 * 1829 *
1792 * @see #drawRoundRectangle 1830 * @see #drawRoundRectangle
1793 */ 1831 */
1794 public void fillRoundRectangle(int x, int y, int width, int height, int arcWidth, int arcHeight) { 1832 public void fillRoundRectangle(int x, int y, int width, int height, int arcWidth, int arcHeight) {
1795 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 1833 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
1796 NSGraphicsContext context = NSGraphicsContext.currentContext();
1797 NSGraphicsContext.setCurrentContext(handle);
1798 checkGC(FILL);
1799 if (arcWidth is 0 || arcHeight is 0) { 1834 if (arcWidth is 0 || arcHeight is 0) {
1800 fillRectangle(x, y, width, height); 1835 fillRectangle(x, y, width, height);
1801 return; 1836 return;
1802 } 1837 }
1803 NSBezierPath path = data.path; 1838 NSAutoreleasePool pool = checkGC(FILL);
1839 try {
1840 NSBezierPath path = data.path;
1804 NSRect rect = NSRect(); 1841 NSRect rect = NSRect();
1805 rect.x = x; 1842 rect.x = x;
1806 rect.y = y; 1843 rect.y = y;
1807 rect.width = width; 1844 rect.width = width;
1808 rect.height = height; 1845 rect.height = height;
1809 path.appendBezierPathWithRoundedRect(rect, arcWidth, arcHeight); 1846 path.appendBezierPathWithRoundedRect(rect, arcWidth, arcHeight);
1810 Pattern pattern = data.backgroundPattern; 1847 Pattern pattern = data.backgroundPattern;
1811 if (pattern !is null && pattern.gradient !is null) { 1848 if (pattern !is null && pattern.gradient !is null) {
1812 fillPattern(path, pattern); 1849 fillPattern(path, pattern);
1813 } else { 1850 } else {
1814 path.fill(); 1851 path.fill();
1815 } 1852 }
1816 path.removeAllPoints(); 1853 path.removeAllPoints();
1817 NSGraphicsContext.setCurrentContext(context); 1854 } finally {
1855 uncheckGC(pool);
1856 }
1818 } 1857 }
1819 1858
1820 void flush () { 1859 void flush () {
1860 handle.flushGraphics();
1821 } 1861 }
1822 1862
1823 /** 1863 /**
1824 * Returns the <em>advance width</em> of the specified character in 1864 * Returns the <em>advance width</em> of the specified character in
1825 * the font which is currently selected into the receiver. 1865 * the font which is currently selected into the receiver.
1903 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 1943 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
1904 return true; 1944 return true;
1905 } 1945 }
1906 1946
1907 /** 1947 /**
1908 * Returns the receiver's alpha value. 1948 * Returns the receiver's alpha value. The alpha value
1949 * is between 0 (transparent) and 255 (opaque).
1909 * 1950 *
1910 * @return the alpha value 1951 * @return the alpha value
1911 * 1952 *
1912 * @exception DWTException <ul> 1953 * @exception DWTException <ul>
1913 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 1954 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
1977 */ 2018 */
1978 public Rectangle getClipping() { 2019 public Rectangle getClipping() {
1979 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 2020 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
1980 NSRect rect; 2021 NSRect rect;
1981 if (data.view !is null) { 2022 if (data.view !is null) {
1982 rect = data.view.bounds(); 2023 rect = data.view.visibleRect();
1983 } else { 2024 } else {
1984 rect = NSRect(); 2025 rect = NSRect();
1985 if (data.image !is null) { 2026 if (data.image !is null) {
1986 NSSize size = data.image.handle.size(); 2027 NSSize size = data.image.handle.size();
1987 rect.width = size.width; 2028 rect.width = size.width;
2036 if (region is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); 2077 if (region is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
2037 if (region.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); 2078 if (region.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
2038 region.subtract(region); 2079 region.subtract(region);
2039 NSRect rect = void; 2080 NSRect rect = void;
2040 if (data.view !is null) { 2081 if (data.view !is null) {
2041 rect = data.view.bounds(); 2082 rect = data.view.visibleRect();
2042 } else { 2083 } else {
2043 rect = NSRect(); 2084 rect = NSRect();
2044 if (data.image !is null) { 2085 if (data.image !is null) {
2045 NSSize size = data.image.handle.size(); 2086 NSSize size = data.image.handle.size();
2046 rect.width = size.width; 2087 rect.width = size.width;
2055 if (paintRect !is null) { 2096 if (paintRect !is null) {
2056 region.intersect(cast(int)paintRect.x, cast(int)paintRect.y, cast(int)paintRect.width, cast(int)paintRect.height); 2097 region.intersect(cast(int)paintRect.x, cast(int)paintRect.y, cast(int)paintRect.width, cast(int)paintRect.height);
2057 } 2098 }
2058 if (data.clipPath !is null) { 2099 if (data.clipPath !is null) {
2059 NSBezierPath clip = data.clipPath.bezierPathByFlatteningPath(); 2100 NSBezierPath clip = data.clipPath.bezierPathByFlatteningPath();
2060 int count = clip.elementCount(); 2101 int count = (int)/*64*/clip.elementCount();
2061 int pointCount = 0; 2102 int pointCount = 0;
2062 Region clipRgn = new Region(device); 2103 Region clipRgn = new Region(device);
2063 int[] pointArray = new int[count * 2]; 2104 int[] pointArray = new int[count * 2];
2064 NSPointArray points = cast(NSPointArray) OS.malloc(NSPoint.sizeof); 2105 NSPointArray points = cast(NSPointArray) OS.malloc(NSPoint.sizeof);
2065 if (points is null) DWT.error(DWT.ERROR_NO_HANDLES); 2106 if (points is null) DWT.error(DWT.ERROR_NO_HANDLES);
2066 NSPoint pt = NSPoint(); 2107 NSPoint pt = NSPoint();
2067 for (int i = 0; i < count; i++) { 2108 for (int i = 0; i < count; i++) {
2068 NSBezierPathElement element = clip.elementAtIndex_associatedPoints_(i, points); 2109 NSBezierPathElement element = clip.elementAtIndex(i, points);
2069 switch (element) { 2110 switch (element) {
2070 case NSMoveToBezierPathElement: 2111 case NSMoveToBezierPathElement:
2071 if (pointCount !is 0) clipRgn.add(pointArray, pointCount); 2112 if (pointCount !is 0) clipRgn.add(pointArray, pointCount);
2072 pointCount = 0; 2113 pointCount = 0;
2073 OS.memmove(&pt, points, NSPoint.sizeof); 2114 OS.memmove(&pt, points, NSPoint.sizeof);
2138 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 2179 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
2139 * </ul> 2180 * </ul>
2140 */ 2181 */
2141 public FontMetrics getFontMetrics() { 2182 public FontMetrics getFontMetrics() {
2142 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 2183 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
2143 checkGC(FONT); 2184 NSAutoreleasePool pool = checkGC(FONT);
2144 NSFont font = data.font.handle; 2185 try {
2186 NSFont font = data.font.handle;
2145 int ascent = cast(int)(0.5f + font.ascender()); 2187 int ascent = cast(int)(0.5f + font.ascender());
2146 int descent = cast(int)(0.5f + (-font.descender() + font.leading())); 2188 int descent = cast(int)(0.5f + (-font.descender() + font.leading()));
2147 String s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 2189 String s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
2148 int averageCharWidth = stringExtent(s).x / s.length(); 2190 int averageCharWidth = stringExtent(s).x / s.length();
2149 return FontMetrics.cocoa_new(ascent, descent, averageCharWidth, 0, ascent + descent); 2191 return FontMetrics.cocoa_new(ascent, descent, averageCharWidth, 0, ascent + descent);
2192 } finally {
2193 uncheckGC(pool);
2194 }
2150 } 2195 }
2151 2196
2152 /** 2197 /**
2153 * Returns the receiver's foreground color. 2198 * Returns the receiver's foreground color.
2154 * 2199 *
2220 * 2265 *
2221 * @since 3.1 2266 * @since 3.1
2222 */ 2267 */
2223 public int getInterpolation() { 2268 public int getInterpolation() {
2224 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 2269 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
2225 int interpolation = handle.imageInterpolation(); 2270 int interpolation = (int)/*64*/handle.imageInterpolation();
2226 switch (interpolation) { 2271 switch (interpolation) {
2227 case OS.NSImageInterpolationDefault: return DWT.DEFAULT; 2272 case OS.NSImageInterpolationDefault: return DWT.DEFAULT;
2228 case OS.NSImageInterpolationNone: return DWT.NONE; 2273 case OS.NSImageInterpolationNone: return DWT.NONE;
2229 case OS.NSImageInterpolationLow: return DWT.LOW; 2274 case OS.NSImageInterpolationLow: return DWT.LOW;
2230 case OS.NSImageInterpolationHigh: return DWT.HIGH; 2275 case OS.NSImageInterpolationHigh: return DWT.HIGH;
2570 setTransform(null); 2615 setTransform(null);
2571 } 2616 }
2572 } 2617 }
2573 2618
2574 /** 2619 /**
2575 * Sets the receiver's alpha value. 2620 * Sets the receiver's alpha value which must be
2621 * between 0 (transparent) and 255 (opaque).
2576 * <p> 2622 * <p>
2577 * This operation requires the operating system's advanced 2623 * This operation requires the operating system's advanced
2578 * graphics subsystem which may not be available on some 2624 * graphics subsystem which may not be available on some
2579 * platforms. 2625 * platforms.
2580 * </p> 2626 * </p>
3435 * </ul> 3481 * </ul>
3436 */ 3482 */
3437 public Point textExtent(String string, int flags) { 3483 public Point textExtent(String string, int flags) {
3438 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED); 3484 if (handle is null) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
3439 if (string is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); 3485 if (string is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
3440 checkGC(FONT); 3486 NSAutoreleasePool pool = checkGC(FONT);
3441 NSAttributedString str = createString(string, flags); 3487 try {
3442 NSSize size = str.size(); 3488 NSAttributedString str = createString(string, flags);
3489 NSSize size = str.size();
3443 return new Point(cast(int)size.width, cast(int)size.height); 3490 return new Point(cast(int)size.width, cast(int)size.height);
3491 } finally {
3492 uncheckGC(pool);
3493 }
3444 } 3494 }
3445 3495
3446 /** 3496 /**
3447 * Returns a string containing a concise, human-readable 3497 * Returns a string containing a concise, human-readable
3448 * description of the receiver. 3498 * description of the receiver.
3452 public String toString () { 3502 public String toString () {
3453 if (isDisposed()) return "GC {*DISPOSED*}"; 3503 if (isDisposed()) return "GC {*DISPOSED*}";
3454 return Format("GC {{}{}" , handle , "}"); 3504 return Format("GC {{}{}" , handle , "}");
3455 } 3505 }
3456 3506
3457 } 3507 void uncheckGC(NSAutoreleasePool pool) {
3508 NSView view = data.view;
3509 if (view !is null && data.paintRect is null) {
3510 if (data.thread !is Thread.currentThread()) flush();
3511 }
3512 if (pool !is null) pool.release();
3513 }
3514
3515 }