diff options
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics')
15 files changed, 0 insertions, 11793 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Color.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Color.java deleted file mode 100644 index ee344c9666..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Color.java +++ /dev/null @@ -1,266 +0,0 @@ -/******************************************************************************* - * 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.swt.graphics; - - -import org.eclipse.swt.*; - -/** - * Instances of this class manage the operating system resources that - * implement SWT's RGB color model. To create a color you can either - * specify the individual color components as integers in the range - * 0 to 255 or provide an instance of an <code>RGB</code>. - * <p> - * Application code must explicitly invoke the <code>Color.dispose()</code> - * method to release the operating system resources managed by each instance - * when those instances are no longer required. - * </p> - * - * @see RGB - * @see Device#getSystemColor - * @see <a href="http://www.eclipse.org/swt/snippets/#color">Color and RGB snippets</a> - * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: PaintExample</a> - * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> - */ -public final class Color extends Resource { - /** - * the handle to the OS color resource - * (Warning: This field is platform dependent) - * <p> - * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT - * public API. It is marked public only so that it can be shared - * within the packages provided by SWT. It is not available on all - * platforms and should never be accessed from application code. - * </p> - */ - public float[] handle; - -Color(Device device) { - super(device); -} - -/** - * Constructs a new instance of this class given a device and the - * desired red, green and blue values expressed as ints in the range - * 0 to 255 (where 0 is black and 255 is full brightness). On limited - * color devices, the color instance created by this call may not have - * the same RGB values as the ones specified by the arguments. The - * RGB values on the returned instance will be the color values of - * the operating system color. - * <p> - * You must dispose the color when it is no longer required. - * </p> - * - * @param device the device on which to allocate the color - * @param red the amount of red in the color - * @param green the amount of green in the color - * @param blue the amount of blue in the color - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li> - * <li>ERROR_INVALID_ARGUMENT - if the red, green or blue argument is not between 0 and 255</li> - * </ul> - * - * @see #dispose - */ -public Color(Device device, int red, int green, int blue) { - super(device); - init(red, green, blue); - init(); -} - -/** - * Constructs a new instance of this class given a device and an - * <code>RGB</code> describing the desired red, green and blue values. - * On limited color devices, the color instance created by this call - * may not have the same RGB values as the ones specified by the - * argument. The RGB values on the returned instance will be the color - * values of the operating system color. - * <p> - * You must dispose the color when it is no longer required. - * </p> - * - * @param device the device on which to allocate the color - * @param rgb the RGB values of the desired color - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li> - * <li>ERROR_NULL_ARGUMENT - if the rgb argument is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the red, green or blue components of the argument are not between 0 and 255</li> - * </ul> - * - * @see #dispose - */ -public Color(Device device, RGB rgb) { - super(device); - if (rgb == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - init(rgb.red, rgb.green, rgb.blue); - init(); -} - -void destroy() { - handle = null; -} - -/** - * Compares the argument to the receiver, and returns true - * if they represent the <em>same</em> object using a class - * specific comparison. - * - * @param object the object to compare with this object - * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise - * - * @see #hashCode - */ -public boolean equals(Object object) { - if (object == this) return true; - if (!(object instanceof Color)) return false; - Color color = (Color)object; - float[] rgbColor = color.handle; - if (handle == rgbColor) return true; - return device == color.device && - (int)(handle[0] * 255) == (int)(rgbColor[0] * 255) && - (int)(handle[1] * 255) == (int)(rgbColor[1] * 255) && - (int)(handle[2] * 255) == (int)(rgbColor[2] * 255); -} - -/** - * Returns the amount of blue in the color, from 0 to 255. - * - * @return the blue component of the color - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public int getBlue() { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - return (int)(handle[2] * 255); -} - -/** - * Returns the amount of green in the color, from 0 to 255. - * - * @return the green component of the color - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public int getGreen() { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - return (int)(handle[1] * 255); -} - -/** - * Returns the amount of red in the color, from 0 to 255. - * - * @return the red component of the color - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public int getRed() { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - return (int)(handle[0] * 255); -} - -/** - * Returns an integer hash code for the receiver. Any two - * objects that return <code>true</code> when passed to - * <code>equals</code> must return the same value for this - * method. - * - * @return the receiver's hash - * - * @see #equals - */ -public int hashCode() { - if (isDisposed()) return 0; - return (int)(handle[0] * 255) ^ (int)(handle[1] * 255) ^ (int)(handle[2] * 255); -} - -/** - * Returns an <code>RGB</code> representing the receiver. - * - * @return the RGB for the color - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public RGB getRGB () { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - return new RGB(getRed(), getGreen(), getBlue()); -} - -/** - * Invokes platform specific functionality to allocate a new color. - * <p> - * <b>IMPORTANT:</b> This method is <em>not</em> part of the public - * API for <code>Color</code>. It is marked public only so that it - * can be shared within the packages provided by SWT. It is not - * available on all platforms, and should never be called from - * application code. - * </p> - * - * @param device the device on which to allocate the color - * @param handle the handle for the color - * - * @private - */ -public static Color carbon_new(Device device, float[] rgbColor) { - Color color = new Color(device); - color.handle = rgbColor; - return color; -} - -void init( int red, int green, int blue) { - if ((red > 255) || (red < 0) || - (green > 255) || (green < 0) || - (blue > 255) || (blue < 0)) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - float[] rgbColor = new float[4]; - rgbColor[0] = red / 255f; - rgbColor[1] = green / 255f; - rgbColor[2] = blue / 255f; - rgbColor[3] = 1; - handle = rgbColor; -} - -/** - * Returns <code>true</code> if the color has been disposed, - * and <code>false</code> otherwise. - * <p> - * This method gets the dispose state for the color. - * When a color has been disposed, it is an error to - * invoke any other method using the color. - * - * @return <code>true</code> when the color is disposed and <code>false</code> otherwise - */ -public boolean isDisposed() { - return handle == null; -} - -/** - * Returns a string containing a concise, human-readable - * description of the receiver. - * - * @return a string representation of the receiver - */ -public String toString () { - if (isDisposed()) return "Color {*DISPOSED*}"; - return "Color {" + getRed() + ", " + getGreen() + ", " + getBlue() + "}"; -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Cursor.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Cursor.java deleted file mode 100644 index 1652463be0..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Cursor.java +++ /dev/null @@ -1,645 +0,0 @@ -/******************************************************************************* - * 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.swt.graphics; - - -import org.eclipse.swt.internal.carbon.*; -import org.eclipse.swt.internal.cocoa.*; -import org.eclipse.swt.*; - -/** - * Instances of this class manage operating system resources that - * specify the appearance of the on-screen pointer. To create a - * cursor you specify the device and either a simple cursor style - * describing one of the standard operating system provided cursors - * or the image and mask data for the desired appearance. - * <p> - * Application code must explicitly invoke the <code>Cursor.dispose()</code> - * method to release the operating system resources managed by each instance - * when those instances are no longer required. - * </p> - * <dl> - * <dt><b>Styles:</b></dt> - * <dd> - * CURSOR_ARROW, CURSOR_WAIT, CURSOR_CROSS, CURSOR_APPSTARTING, CURSOR_HELP, - * CURSOR_SIZEALL, CURSOR_SIZENESW, CURSOR_SIZENS, CURSOR_SIZENWSE, CURSOR_SIZEWE, - * CURSOR_SIZEN, CURSOR_SIZES, CURSOR_SIZEE, CURSOR_SIZEW, CURSOR_SIZENE, CURSOR_SIZESE, - * CURSOR_SIZESW, CURSOR_SIZENW, CURSOR_UPARROW, CURSOR_IBEAM, CURSOR_NO, CURSOR_HAND - * </dd> - * </dl> - * <p> - * Note: Only one of the above styles may be specified. - * </p> - * - * @see <a href="http://www.eclipse.org/swt/snippets/#cursor">Cursor snippets</a> - * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> - */ - -public final class Cursor extends Resource { - - /** - * the handle to the OS cursor resource - * (Warning: This field is platform dependent) - * <p> - * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT - * public API. It is marked public only so that it can be shared - * within the packages provided by SWT. It is not available on all - * platforms and should never be accessed from application code. - * </p> - */ - public int handle; - - static boolean initialized; - -/** - * Prevents uninitialized instances from being created outside the package. - */ -Cursor(Device device) { - super(device); -} - -/** - * Constructs a new cursor given a device and a style - * constant describing the desired cursor appearance. - * <p> - * You must dispose the cursor when it is no longer required. - * </p> - * - * @param device the device on which to allocate the cursor - * @param style the style of cursor to allocate - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li> - * <li>ERROR_INVALID_ARGUMENT - when an unknown style is specified</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES - if a handle could not be obtained for cursor creation</li> - * </ul> - * - * @see SWT#CURSOR_ARROW - * @see SWT#CURSOR_WAIT - * @see SWT#CURSOR_CROSS - * @see SWT#CURSOR_APPSTARTING - * @see SWT#CURSOR_HELP - * @see SWT#CURSOR_SIZEALL - * @see SWT#CURSOR_SIZENESW - * @see SWT#CURSOR_SIZENS - * @see SWT#CURSOR_SIZENWSE - * @see SWT#CURSOR_SIZEWE - * @see SWT#CURSOR_SIZEN - * @see SWT#CURSOR_SIZES - * @see SWT#CURSOR_SIZEE - * @see SWT#CURSOR_SIZEW - * @see SWT#CURSOR_SIZENE - * @see SWT#CURSOR_SIZESE - * @see SWT#CURSOR_SIZESW - * @see SWT#CURSOR_SIZENW - * @see SWT#CURSOR_UPARROW - * @see SWT#CURSOR_IBEAM - * @see SWT#CURSOR_NO - * @see SWT#CURSOR_HAND - */ -public Cursor(Device device, int style) { - super(device); - switch (style) { - case SWT.CURSOR_HAND: handle = OS.kThemePointingHandCursor; break; - case SWT.CURSOR_ARROW: handle = OS.kThemeArrowCursor; break; - case SWT.CURSOR_WAIT: handle = OS.kThemeSpinningCursor; break; - case SWT.CURSOR_CROSS: handle = OS.kThemeCrossCursor; break; - case SWT.CURSOR_APPSTARTING: handle = OS.kThemeArrowCursor; break; - case SWT.CURSOR_HELP: handle = OS.kThemeCrossCursor; break; - case SWT.CURSOR_SIZEALL: handle = OS.kThemeCrossCursor; break; - case SWT.CURSOR_SIZENESW: handle = OS.kThemeCrossCursor; break; - case SWT.CURSOR_SIZENS: handle = OS.kThemeResizeUpDownCursor; break; - case SWT.CURSOR_SIZENWSE: handle = OS.kThemeCrossCursor; break; - case SWT.CURSOR_SIZEWE: handle = OS.kThemeResizeLeftRightCursor; break; - case SWT.CURSOR_SIZEN: handle = OS.kThemeResizeUpCursor; break; - case SWT.CURSOR_SIZES: handle = OS.kThemeResizeDownCursor; break; - case SWT.CURSOR_SIZEE: handle = OS.kThemeResizeRightCursor; break; - case SWT.CURSOR_SIZEW: handle = OS.kThemeResizeLeftCursor; break; - case SWT.CURSOR_SIZENE: handle = OS.kThemeCrossCursor; break; - case SWT.CURSOR_SIZESE: handle = OS.kThemeCrossCursor; break; - case SWT.CURSOR_SIZESW: handle = OS.kThemeCrossCursor; break; - case SWT.CURSOR_SIZENW: handle = OS.kThemeCrossCursor; break; - case SWT.CURSOR_UPARROW: handle = OS.kThemeCrossCursor; break; - case SWT.CURSOR_IBEAM: handle = OS.kThemeIBeamCursor; break; - case SWT.CURSOR_NO: handle = OS.kThemeNotAllowedCursor; break; - default: - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - init(); -} - -/** - * Constructs a new cursor given a device, image and mask - * data describing the desired cursor appearance, and the x - * and y coordinates of the <em>hotspot</em> (that is, the point - * within the area covered by the cursor which is considered - * to be where the on-screen pointer is "pointing"). - * <p> - * The mask data is allowed to be null, but in this case the source - * must be an ImageData representing an icon that specifies both - * color data and mask data. - * <p> - * You must dispose the cursor when it is no longer required. - * </p> - * - * @param device the device on which to allocate the cursor - * @param source the color data for the cursor - * @param mask the mask data for the cursor (or null) - * @param hotspotX the x coordinate of the cursor's hotspot - * @param hotspotY the y coordinate of the cursor's hotspot - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li> - * <li>ERROR_NULL_ARGUMENT - if the source is null</li> - * <li>ERROR_NULL_ARGUMENT - if the mask is null and the source does not have a mask</li> - * <li>ERROR_INVALID_ARGUMENT - if the source and the mask are not the same - * size, or if the hotspot is outside the bounds of the image</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES - if a handle could not be obtained for cursor creation</li> - * </ul> - */ -public Cursor(Device device, ImageData source, ImageData mask, int hotspotX, int hotspotY) { - super(device); - if (source == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (mask == null) { - if (source.getTransparencyType() != SWT.TRANSPARENCY_MASK) { - SWT.error(SWT.ERROR_NULL_ARGUMENT); - } - mask = source.getTransparencyMask(); - } - /* Check the bounds. Mask must be the same size as source */ - if (mask.width != source.width || mask.height != source.height) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - /* Check the hotspots */ - if (hotspotX >= source.width || hotspotX < 0 || - hotspotY >= source.height || hotspotY < 0) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - if (OS.VERSION >= 0x1040) { - byte[] data = new byte[source.width * source.height * 4]; - for (int y = 0; y < source.height; y++) { - int offset = y * source.width * 4; - for (int x = 0; x < source.width; x++) { - int pixel = source.getPixel(x, y); - int maskPixel = mask.getPixel(x, y); - if (pixel == 0 && maskPixel == 0) { - // BLACK - data[offset] = (byte)0xFF; - } else if (pixel == 0 && maskPixel == 1) { - // WHITE - cursor color - data[offset] = data[offset + 1] = data[offset + 2] = data[offset + 3] = (byte)0xFF; - } else if (pixel == 1 && maskPixel == 0) { - // SCREEN - } else { - /* - * Feature in the Macintosh. It is not possible to have - * the reverse screen case using NSCursor. - * Reverse screen will be the same as screen. - */ - // REVERSE SCREEN -> SCREEN - } - offset += 4; - } - } - createNSCursor(hotspotX, hotspotY, data, source.width, source.height); - return; - } - /* Convert depth to 1 */ - mask = ImageData.convertMask(mask); - source = ImageData.convertMask(source); - - /* Find the first non transparent pixel if cursor bigger than 16x16. */ - int width = source.width; - int height = source.height; - int minX = 0, minY = 0; - if (width > 16 || height > 16) { - minX = width; - minY = height; - int maxX = 0, maxY = 0; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - if (!(source.getPixel(x, y) == 1 && mask.getPixel(x, y) == 0)) { - minX = Math.min(minX, x); - minY = Math.min(minY, y); - maxX = Math.max(maxX, x); - maxY = Math.max(maxY, y); - } - } - } - width = maxX - minX + 1; - height = maxY - minY + 1; - - /* Stretch cursor if still bigger than 16x16. */ - if (width > 16 || height > 16) { - int newWidth = Math.min(width, 16); - int newHeight = Math.min(height, 16); - ImageData newSource = - new ImageData(newWidth, newHeight, source.depth, source.palette, - 1, null, 0, null, null, -1, -1, source.type, - source.x, source.y, source.disposalMethod, source.delayTime); - ImageData newMask = new ImageData(newWidth, newHeight, mask.depth, - mask.palette, 1, null, 0, null, null, -1, -1, mask.type, - mask.x, mask.y, mask.disposalMethod, mask.delayTime); - ImageData.blit(ImageData.BLIT_SRC, - source.data, source.depth, source.bytesPerLine, source.getByteOrder(), minX, minY, width, height, null, null, null, - ImageData.ALPHA_OPAQUE, null, 0, minX, minY, - newSource.data, newSource.depth, newSource.bytesPerLine, newSource.getByteOrder(), 0, 0, newWidth, newHeight, null, null, null, - false, false); - ImageData.blit(ImageData.BLIT_SRC, - mask.data, mask.depth, mask.bytesPerLine, mask.getByteOrder(), minX, minY, width, height, null, null, null, - ImageData.ALPHA_OPAQUE, null, 0, minX, minY, - newMask.data, newMask.depth, newMask.bytesPerLine, newMask.getByteOrder(), 0, 0, newWidth, newHeight, null, null, null, - false, false); - width = newWidth; - height = newHeight; - minX = minY = 0; - source = newSource; - mask = newMask; - } - } - - /* Create the cursor */ - org.eclipse.swt.internal.carbon.Cursor cursor = new org.eclipse.swt.internal.carbon.Cursor(); - byte[] srcData = cursor.data; - byte[] maskData = cursor.mask; - for (int y = 0; y < height; y++) { - short d = 0, m = 0; - for (int x = 0; x < width; x++) { - int bit = 1 << (width - 1 - x); - if (source.getPixel(minX + x, minY + y) == 0) { - m |= bit; - if (mask.getPixel(minX + x, minY + y) == 0) d |= bit; - } else if (mask.getPixel(minX + x, minY + y) != 0) { - d |= bit; - } - } - srcData[y * 2] = (byte)(d >> 8); - srcData[y * 2 + 1] = (byte)(d & 0xFF); - maskData[y * 2] = (byte)(m >> 8); - maskData[y * 2 + 1] = (byte)(m & 0xFF); - } - cursor.hotSpot_h = (short)Math.max(0, Math.min(15, hotspotX - minX)); - cursor.hotSpot_v = (short)Math.max(0, Math.min(15, hotspotY - minY)); - handle = OS.NewPtr(org.eclipse.swt.internal.carbon.Cursor.sizeof); - if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); - OS.memmove(handle, cursor, org.eclipse.swt.internal.carbon.Cursor.sizeof); - init(); -} - -void createNSCursor(int hotspotX, int hotspotY, byte[] buffer, int width, int height) { - if (!initialized) { - initialized = true; - int window = Cocoa.objc_msgSend(Cocoa.objc_msgSend(Cocoa.C_NSWindow, Cocoa.S_alloc), Cocoa.S_init); - Cocoa.objc_msgSend(window, Cocoa.S_release); - } - int nsImage = Cocoa.objc_msgSend(Cocoa.C_NSImage, Cocoa.S_alloc); - if (nsImage == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int nsImageRep = Cocoa.objc_msgSend(Cocoa.C_NSBitmapImageRep, Cocoa.S_alloc); - if (nsImageRep == 0) SWT.error(SWT.ERROR_NO_HANDLES); - this.handle = Cocoa.objc_msgSend(Cocoa.C_NSCursor, Cocoa.S_alloc); - if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); - NSSize size = new NSSize(); - size.width = width; - size.height = height; - nsImage = Cocoa.objc_msgSend(nsImage, Cocoa.S_initWithSize, size); - nsImageRep = Cocoa.objc_msgSend(nsImageRep, Cocoa.S_initWithBitmapDataPlanes, null, width, height, - 8, 4, 1, 0, Cocoa.NSDeviceRGBColorSpace(), - Cocoa.NSAlphaFirstBitmapFormat | Cocoa.NSAlphaNonpremultipliedBitmapFormat, width * 4, 32); - int bitmapData = Cocoa.objc_msgSend(nsImageRep, Cocoa.S_bitmapData); - OS.memmove(bitmapData, buffer, buffer.length); - Cocoa.objc_msgSend(nsImage, Cocoa.S_addRepresentation, nsImageRep); - NSPoint point = new NSPoint(); - point.x = hotspotX; - point.y = hotspotY; - handle = Cocoa.objc_msgSend(handle, Cocoa.S_initWithImage_hotSpot, nsImage, point); - Cocoa.objc_msgSend(nsImage, Cocoa.S_release); - Cocoa.objc_msgSend(nsImageRep, Cocoa.S_release); -} - -/** - * Constructs a new cursor given a device, image data describing - * the desired cursor appearance, and the x and y coordinates of - * the <em>hotspot</em> (that is, the point within the area - * covered by the cursor which is considered to be where the - * on-screen pointer is "pointing"). - * <p> - * You must dispose the cursor when it is no longer required. - * </p> - * - * @param device the device on which to allocate the cursor - * @param source the image data for the cursor - * @param hotspotX the x coordinate of the cursor's hotspot - * @param hotspotY the y coordinate of the cursor's hotspot - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li> - * <li>ERROR_NULL_ARGUMENT - if the image is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the hotspot is outside the bounds of the - * image</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES - if a handle could not be obtained for cursor creation</li> - * </ul> - * - * @since 3.0 - */ -public Cursor(Device device, ImageData source, int hotspotX, int hotspotY) { - super(device); - if (source == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (hotspotX >= source.width || hotspotX < 0 || - hotspotY >= source.height || hotspotY < 0) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - - if (OS.VERSION >= 0x1040) { - byte[] data = new byte[source.width * source.height * 4]; - PaletteData palette = source.palette; - if (palette.isDirect) { - ImageData.blit(ImageData.BLIT_SRC, - source.data, source.depth, source.bytesPerLine, source.getByteOrder(), 0, 0, source.width, source.height, palette.redMask, palette.greenMask, palette.blueMask, - ImageData.ALPHA_OPAQUE, null, 0, 0, 0, - data, 32, source.width * 4, ImageData.MSB_FIRST, 0, 0, source.width, source.height, 0xFF0000, 0xFF00, 0xFF, - false, false); - } else { - RGB[] rgbs = palette.getRGBs(); - int length = rgbs.length; - byte[] srcReds = new byte[length]; - byte[] srcGreens = new byte[length]; - byte[] srcBlues = new byte[length]; - for (int i = 0; i < rgbs.length; i++) { - RGB rgb = rgbs[i]; - if (rgb == null) continue; - srcReds[i] = (byte)rgb.red; - srcGreens[i] = (byte)rgb.green; - srcBlues[i] = (byte)rgb.blue; - } - ImageData.blit(ImageData.BLIT_SRC, - source.data, source.depth, source.bytesPerLine, source.getByteOrder(), 0, 0, source.width, source.height, srcReds, srcGreens, srcBlues, - ImageData.ALPHA_OPAQUE, null, 0, 0, 0, - data, 32, source.width * 4, ImageData.MSB_FIRST, 0, 0, source.width, source.height, 0xFF0000, 0xFF00, 0xFF, - false, false); - } - if (source.maskData != null || source.transparentPixel != -1) { - ImageData mask = source.getTransparencyMask(); - byte[] maskData = mask.data; - int maskBpl = mask.bytesPerLine; - int offset = 0, maskOffset = 0; - for (int y = 0; y<source.height; y++) { - for (int x = 0; x<source.width; x++) { - data[offset] = ((maskData[maskOffset + (x >> 3)]) & (1 << (7 - (x & 0x7)))) != 0 ? (byte)0xff : 0; - offset += 4; - } - maskOffset += maskBpl; - } - } else if (source.alpha != -1) { - byte alpha = (byte)source.alpha; - for (int i=0; i<data.length; i+=4) { - data[i] = alpha; - } - } else if (source.alphaData != null) { - byte[] alphaData = source.alphaData; - for (int i=0; i<data.length; i+=4) { - data[i] = alphaData[i/4]; - } - } - createNSCursor(hotspotX, hotspotY, data, source.width, source.height); - } else { - - ImageData mask = source.getTransparencyMask(); - - /* Ensure depth is equal to 1 */ - if (source.depth > 1) { - /* Create a destination image with no data */ - ImageData newSource = new ImageData( - source.width, source.height, 1, ImageData.bwPalette(), - 1, null, 0, null, null, -1, -1, 0, 0, 0, 0, 0); - - byte[] newReds = new byte[]{0, (byte)255}, newGreens = newReds, newBlues = newReds; - - /* Convert the source to a black and white image of depth 1 */ - PaletteData palette = source.palette; - if (palette.isDirect) { - ImageData.blit(ImageData.BLIT_SRC, - source.data, source.depth, source.bytesPerLine, source.getByteOrder(), 0, 0, source.width, source.height, palette.redMask, palette.greenMask, palette.blueMask, - ImageData.ALPHA_OPAQUE, null, 0, 0, 0, - newSource.data, newSource.depth, newSource.bytesPerLine, newSource.getByteOrder(), 0, 0, newSource.width, newSource.height, newReds, newGreens, newBlues, - false, false); - } else { - RGB[] rgbs = palette.getRGBs(); - int length = rgbs.length; - byte[] srcReds = new byte[length]; - byte[] srcGreens = new byte[length]; - byte[] srcBlues = new byte[length]; - for (int i = 0; i < rgbs.length; i++) { - RGB rgb = rgbs[i]; - if (rgb == null) continue; - srcReds[i] = (byte)rgb.red; - srcGreens[i] = (byte)rgb.green; - srcBlues[i] = (byte)rgb.blue; - } - ImageData.blit(ImageData.BLIT_SRC, - source.data, source.depth, source.bytesPerLine, source.getByteOrder(), 0, 0, source.width, source.height, srcReds, srcGreens, srcBlues, - ImageData.ALPHA_OPAQUE, null, 0, 0, 0, - newSource.data, newSource.depth, newSource.bytesPerLine, newSource.getByteOrder(), 0, 0, newSource.width, newSource.height, newReds, newGreens, newBlues, - false, false); - } - source = newSource; - } - - /* Find the first non transparent pixel if cursor bigger than 16x16. */ - int width = source.width; - int height = source.height; - int minX = 0, minY = 0; - if (width > 16 || height > 16) { - minX = width; - minY = height; - int maxX = 0, maxY = 0; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - if (!(source.getPixel(x, y) == 1 && mask.getPixel(x, y) == 0)) { - minX = Math.min(minX, x); - minY = Math.min(minY, y); - maxX = Math.max(maxX, x); - maxY = Math.max(maxY, y); - } - } - } - width = maxX - minX + 1; - height = maxY - minY + 1; - - /* Stretch cursor if still bigger than 16x16. */ - if (width > 16 || height > 16) { - int newWidth = Math.min(width, 16); - int newHeight = Math.min(height, 16); - ImageData newSource = - new ImageData(newWidth, newHeight, source.depth, source.palette, - 1, null, 0, null, null, -1, -1, source.type, - source.x, source.y, source.disposalMethod, source.delayTime); - ImageData newMask = new ImageData(newWidth, newHeight, mask.depth, - mask.palette, 1, null, 0, null, null, -1, -1, mask.type, - mask.x, mask.y, mask.disposalMethod, mask.delayTime); - ImageData.blit(ImageData.BLIT_SRC, - source.data, source.depth, source.bytesPerLine, source.getByteOrder(), minX, minY, width, height, null, null, null, - ImageData.ALPHA_OPAQUE, null, 0, minX, minY, - newSource.data, newSource.depth, newSource.bytesPerLine, newSource.getByteOrder(), 0, 0, newWidth, newHeight, null, null, null, - false, false); - ImageData.blit(ImageData.BLIT_SRC, - mask.data, mask.depth, mask.bytesPerLine, mask.getByteOrder(), minX, minY, width, height, null, null, null, - ImageData.ALPHA_OPAQUE, null, 0, minX, minY, - newMask.data, newMask.depth, newMask.bytesPerLine, newMask.getByteOrder(), 0, 0, newWidth, newHeight, null, null, null, - false, false); - width = newWidth; - height = newHeight; - minX = minY = 0; - source = newSource; - mask = newMask; - } - } - - /* Create the cursor */ - org.eclipse.swt.internal.carbon.Cursor cursor = new org.eclipse.swt.internal.carbon.Cursor(); - byte[] srcData = cursor.data; - byte[] maskData = cursor.mask; - for (int y= 0; y < height; y++) { - short d = 0, m = 0; - for (int x = 0; x < width; x++) { - int bit = 1 << (width - 1 - x); - if (source.getPixel(x + minX, y + minY) == 0) { - if (mask.getPixel(x + minX, y + minY) != 0) { - d |= bit; - m |= bit; - } - } else { - if (mask.getPixel(x + minX, y + minY) != 0) m |= bit; - } - } - srcData[y * 2] = (byte)(d >> 8); - srcData[y * 2 + 1] = (byte)(d & 0xFF); - maskData[y * 2] = (byte)(m >> 8); - maskData[y * 2 + 1] = (byte)(m & 0xFF); - } - cursor.hotSpot_h = (short)Math.max(0, Math.min(15, hotspotX - minX)); - cursor.hotSpot_v = (short)Math.max(0, Math.min(15, hotspotY - minY)); - handle = OS.NewPtr(org.eclipse.swt.internal.carbon.Cursor.sizeof); - if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); - OS.memmove(handle, cursor, org.eclipse.swt.internal.carbon.Cursor.sizeof); - } - init(); -} - -void destroy() { - switch (handle) { - case OS.kThemePointingHandCursor: - case OS.kThemeArrowCursor: - case OS.kThemeSpinningCursor: - case OS.kThemeCrossCursor: - case OS.kThemeWatchCursor: - case OS.kThemeIBeamCursor: - case OS.kThemeNotAllowedCursor: - case OS.kThemeResizeLeftRightCursor: - case OS.kThemeResizeLeftCursor: - case OS.kThemeResizeRightCursor: - case OS.kThemeResizeUpDownCursor: - case OS.kThemeResizeUpCursor: - case OS.kThemeResizeDownCursor: - break; - default: - if (OS.VERSION >= 0x1040) { - Cocoa.objc_msgSend(handle, Cocoa.S_release); - } else { - OS.DisposePtr(handle); - } - } - handle = -1; -} - -/** - * Compares the argument to the receiver, and returns true - * if they represent the <em>same</em> object using a class - * specific comparison. - * - * @param object the object to compare with this object - * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise - * - * @see #hashCode - */ -public boolean equals (Object object) { - if (object == this) return true; - if (!(object instanceof Cursor)) return false; - Cursor cursor = (Cursor) object; - return device == cursor.device && handle == cursor.handle; -} - -/** - * Returns an integer hash code for the receiver. Any two - * objects that return <code>true</code> when passed to - * <code>equals</code> must return the same value for this - * method. - * - * @return the receiver's hash - * - * @see #equals - */ -public int hashCode () { - return handle; -} - -/** - * Returns <code>true</code> if the cursor has been disposed, - * and <code>false</code> otherwise. - * <p> - * This method gets the dispose state for the cursor. - * When a cursor has been disposed, it is an error to - * invoke any other method using the cursor. - * - * @return <code>true</code> when the cursor is disposed and <code>false</code> otherwise - */ -public boolean isDisposed() { - return handle == -1; -} - -/** - * Returns a string containing a concise, human-readable - * description of the receiver. - * - * @return a string representation of the receiver - */ -public String toString () { - if (isDisposed()) return "Cursor {*DISPOSED*}"; - return "Cursor {" + handle + "}"; -} - -/** - * Invokes platform specific functionality to allocate a new cursor. - * <p> - * <b>IMPORTANT:</b> This method is <em>not</em> part of the public - * API for <code>Cursor</code>. It is marked public only so that it - * can be shared within the packages provided by SWT. It is not - * available on all platforms, and should never be called from - * application code. - * </p> - * - * @param device the device on which to allocate the color - * @param handle the handle for the cursor - * - * @private - */ -public static Cursor carbon_new(Device device, int handle) { - Cursor cursor = new Cursor(device); - cursor.handle = handle; - return cursor; -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Device.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Device.java deleted file mode 100644 index 270a1ca841..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Device.java +++ /dev/null @@ -1,794 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2009 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.swt.graphics; - -import org.eclipse.swt.internal.carbon.*; -import org.eclipse.swt.internal.*; -import org.eclipse.swt.*; - -/** - * This class is the abstract superclass of all device objects, - * such as the Display device and the Printer device. Devices - * can have a graphics context (GC) created for them, and they - * can be drawn on by sending messages to the associated GC. - * - * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> - */ -public abstract class Device implements Drawable { - - /* Debugging */ - public static boolean DEBUG; - boolean debug = DEBUG; - boolean tracking = DEBUG; - Error [] errors; - Object [] objects; - Object trackingLock; - - /* Disposed flag */ - boolean disposed, warnings; - - int colorspace; - - /* - * The following colors are listed in the Windows - * Programmer's Reference as the colors in the default - * palette. - */ - Color COLOR_BLACK, COLOR_DARK_RED, COLOR_DARK_GREEN, COLOR_DARK_YELLOW, COLOR_DARK_BLUE; - Color COLOR_DARK_MAGENTA, COLOR_DARK_CYAN, COLOR_GRAY, COLOR_DARK_GRAY, COLOR_RED; - Color COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE; - - /* System Font */ - Font systemFont; - - /* Device DPI */ - Point dpi; - - /* Callbacks */ - Callback drawPatternCallback, axialShadingCallback, releaseCallback; - int drawPatternProc, axialShadingProc, releaseProc; - - /* - * TEMPORARY CODE. When a graphics object is - * created and the device parameter is null, - * the current Display is used. This presents - * a problem because SWT graphics does not - * reference classes in SWT widgets. The correct - * fix is to remove this feature. Unfortunately, - * too many application programs rely on this - * feature. - */ - protected static Device CurrentDevice; - protected static Runnable DeviceFinder; - static { - try { - Class.forName ("org.eclipse.swt.widgets.Display"); - } catch (ClassNotFoundException e) {} - } - -/* -* TEMPORARY CODE. -*/ -static synchronized Device getDevice () { - if (DeviceFinder != null) DeviceFinder.run(); - Device device = CurrentDevice; - CurrentDevice = null; - return device; -} - -/** - * Constructs a new instance of this class. - * <p> - * You must dispose the device when it is no longer required. - * </p> - * - * @see #create - * @see #init - * - * @since 3.1 - */ -public Device() { - this(null); -} - -/** - * Constructs a new instance of this class. - * <p> - * You must dispose the device when it is no longer required. - * </p> - * - * @param data the DeviceData which describes the receiver - * - * @see #create - * @see #init - * @see DeviceData - */ -public Device(DeviceData data) { - synchronized (Device.class) { - if (data != null) { - debug = data.debug; - tracking = data.tracking; - } - if (tracking) { - errors = new Error [128]; - objects = new Object [128]; - trackingLock = new Object (); - } - create (data); - init (); - } -} - -int axialShadingProc (int ref, int in, int out) { - Object object = OS.JNIGetObject (ref); - if (object instanceof Pattern) { - return ((Pattern) object).axialShadingProc (ref, in, out); - } - return 0; -} - -/** - * Throws an <code>SWTException</code> if the receiver can not - * be accessed by the caller. This may include both checks on - * the state of the receiver and more generally on the entire - * execution context. This method <em>should</em> be called by - * device implementors to enforce the standard SWT invariants. - * <p> - * Currently, it is an error to invoke any method (other than - * <code>isDisposed()</code> and <code>dispose()</code>) on a - * device that has had its <code>dispose()</code> method called. - * </p><p> - * In future releases of SWT, there may be more or fewer error - * checks and exceptions may be thrown for different reasons. - * <p> - * - * @exception SWTException <ul> - * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -protected void checkDevice () { - if (disposed) SWT.error(SWT.ERROR_DEVICE_DISPOSED); -} - -/** - * Creates the device in the operating system. If the device - * does not have a handle, this method may do nothing depending - * on the device. - * <p> - * This method is called before <code>init</code>. - * </p><p> - * Subclasses are supposed to reimplement this method and not - * call the <code>super</code> implementation. - * </p> - * - * @param data the DeviceData which describes the receiver - * - * @see #init - */ -protected void create (DeviceData data) { -} - -void createPatternCallbacks () { - if (drawPatternCallback == null) { - drawPatternCallback = new Callback(this, "drawPatternProc", 2); - drawPatternProc = drawPatternCallback.getAddress(); - if (drawPatternProc == 0) SWT.error(SWT.ERROR_NO_MORE_CALLBACKS); - } - if (axialShadingCallback == null) { - axialShadingCallback = new Callback(this, "axialShadingProc", 3); - axialShadingProc = axialShadingCallback.getAddress(); - if (axialShadingProc == 0) SWT.error(SWT.ERROR_NO_MORE_CALLBACKS); - } -} - -/** - * Disposes of the operating system resources associated with - * the receiver. After this method has been invoked, the receiver - * will answer <code>true</code> when sent the message - * <code>isDisposed()</code>. - * - * @see #release - * @see #destroy - * @see #checkDevice - */ -public void dispose () { - synchronized (Device.class) { - if (isDisposed()) return; - checkDevice (); - release (); - destroy (); - disposed = true; - if (tracking) { - synchronized (trackingLock) { - objects = null; - errors = null; - trackingLock = null; - } - } - } -} - -void dispose_Object (Object object) { - synchronized (trackingLock) { - for (int i=0; i<objects.length; i++) { - if (objects [i] == object) { - objects [i] = null; - errors [i] = null; - return; - } - } - } -} - -/** - * Destroys the device in the operating system and releases - * the device's handle. If the device does not have a handle, - * this method may do nothing depending on the device. - * <p> - * This method is called after <code>release</code>. - * </p><p> - * Subclasses are supposed to reimplement this method and not - * call the <code>super</code> implementation. - * </p> - * - * @see #dispose - * @see #release - */ -protected void destroy () { -} - -int drawPatternProc (int ref, int context) { - Object object = OS.JNIGetObject (ref); - if (object instanceof Pattern) { - return ((Pattern) object).drawPatternProc (ref, context); - } - return 0; -} - -/** - * Returns a rectangle describing the receiver's size and location. - * - * @return the bounding rectangle - * - * @exception SWTException <ul> - * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public Rectangle getBounds () { - checkDevice (); - int gdevice = OS.GetMainDevice(); - int[] ptr = new int[1]; - OS.memmove(ptr, gdevice, 4); - GDevice device = new GDevice(); - OS.memmove(device, ptr[0], GDevice.sizeof); - return new Rectangle(device.left, device.top, device.right - device.left, device.bottom - device.top); -} - -/** - * Returns a <code>DeviceData</code> based on the receiver. - * Modifications made to this <code>DeviceData</code> will not - * affect the receiver. - * - * @return a <code>DeviceData</code> containing the device's data and attributes - * - * @exception SWTException <ul> - * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see DeviceData - */ -public DeviceData getDeviceData () { - checkDevice(); - DeviceData data = new DeviceData (); - data.debug = debug; - data.tracking = tracking; - if (tracking) { - synchronized (trackingLock) { - int count = 0, length = objects.length; - for (int i=0; i<length; i++) { - if (objects [i] != null) count++; - } - int index = 0; - data.objects = new Object [count]; - data.errors = new Error [count]; - for (int i=0; i<length; i++) { - if (objects [i] != null) { - data.objects [index] = objects [i]; - data.errors [index] = errors [i]; - index++; - } - } - } - } else { - data.objects = new Object [0]; - data.errors = new Error [0]; - } - return data; -} - -/** - * Returns a rectangle which describes the area of the - * receiver which is capable of displaying data. - * - * @return the client area - * - * @exception SWTException <ul> - * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #getBounds - */ -public Rectangle getClientArea () { - checkDevice (); - int gdevice = OS.GetMainDevice(); - Rect rect = new Rect(); - OS.GetAvailableWindowPositioningBounds(gdevice, rect); - return new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); -} - -/** - * Returns the bit depth of the screen, which is the number of - * bits it takes to represent the number of unique colors that - * the screen is currently capable of displaying. This number - * will typically be one of 1, 8, 15, 16, 24 or 32. - * - * @return the depth of the screen - * - * @exception SWTException <ul> - * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public int getDepth () { - checkDevice (); - int gdevice = OS.GetMainDevice(); - int[] ptr = new int[1]; - OS.memmove(ptr, gdevice, 4); - GDevice device = new GDevice(); - OS.memmove(device, ptr[0], GDevice.sizeof); - return OS.GetPixDepth(device.gdPMap); -} - -/** - * Returns a point whose x coordinate is the horizontal - * dots per inch of the display, and whose y coordinate - * is the vertical dots per inch of the display. - * - * @return the horizontal and vertical DPI - * - * @exception SWTException <ul> - * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public Point getDPI () { - checkDevice (); - int gdevice = OS.GetMainDevice(); - int[] ptr = new int[1]; - OS.memmove(ptr, gdevice, 4); - GDevice device = new GDevice(); - OS.memmove(device, ptr[0], GDevice.sizeof); - OS.memmove(ptr, device.gdPMap, 4); - PixMap pixmap = new PixMap(); - OS.memmove(pixmap, ptr[0], PixMap.sizeof); - return new Point (OS.Fix2Long (pixmap.hRes), OS.Fix2Long (pixmap.vRes)); -} - -/** - * Returns <code>FontData</code> objects which describe - * the fonts that match the given arguments. If the - * <code>faceName</code> is null, all fonts will be returned. - * - * @param faceName the name of the font to look for, or null - * @param scalable if true only scalable fonts are returned, otherwise only non-scalable fonts are returned. - * @return the matching font data - * - * @exception SWTException <ul> - * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public FontData[] getFontList (String faceName, boolean scalable) { - checkDevice (); - if (!scalable) return new FontData[0]; - int count = 0; - int[] buffer = new int[1]; - CFRange range = new CFRange (); - OS.ATSUGetFontIDs(null, 0, buffer); - FontData[] fds = new FontData[buffer[0]]; - int status = OS.ATSFontIteratorCreate (OS.kATSFontContextLocal, 0, 0, OS.kATSOptionFlagsDefaultScope, buffer); - int iter = buffer[0]; - while (status == OS.noErr) { - status = OS.ATSFontIteratorNext(iter, buffer); - if (status == OS.noErr) { - int font = buffer[0]; - if (OS.ATSFontGetName(font, 0, buffer) == OS.noErr) { - range.length = OS.CFStringGetLength(buffer[0]); - char [] chars = new char[range.length]; - OS.CFStringGetCharacters(buffer[0], range, chars); - OS.CFRelease(buffer[0]); - String atsName = new String(chars); - int platformCode = OS.kFontUnicodePlatform, encoding = OS.kCFStringEncodingUnicode; - if (OS.ATSUFindFontName(font, OS.kFontFamilyName, platformCode, OS.kFontNoScriptCode, OS.kFontNoLanguageCode, 0, null, buffer, null) != OS.noErr) { - platformCode = OS.kFontNoPlatformCode; - encoding = OS.kCFStringEncodingMacRoman; - if (OS.ATSUFindFontName(font, OS.kFontFamilyName, platformCode, OS.kFontNoScriptCode, OS.kFontNoLanguageCode, 0, null, buffer, null) != OS.noErr) { - continue; - } - } - byte[] bytes = new byte[buffer[0]]; - OS.ATSUFindFontName(font, OS.kFontFamilyName, platformCode, OS.kFontNoScriptCode, OS.kFontNoLanguageCode, bytes.length, bytes, buffer, null); - int ptr = OS.CFStringCreateWithBytes(0, bytes, bytes.length, encoding, false); - if (ptr != 0) { - range.length = OS.CFStringGetLength(ptr); - if (range.length != 0) { - chars = new char[range.length]; - OS.CFStringGetCharacters(ptr, range, chars); - String name = new String(chars); - if (!name.startsWith(".")) { - if (faceName == null || Compatibility.equalsIgnoreCase(faceName, name)) { - int s = SWT.NORMAL; - if (atsName.indexOf("Italic") != -1) s |= SWT.ITALIC; - if (atsName.indexOf("Bold") != -1) s |= SWT.BOLD; - FontData data = new FontData(name, 0, s); - data.atsName = atsName; - if (count == fds.length) { - FontData[] newFDs = new FontData[count + 4]; - System.arraycopy(fds, 0, newFDs, 0, count); - fds = newFDs; - } - fds[count++] = data; - } - } - } - OS.CFRelease(ptr); - } - } - } - } - if (iter != 0) { - buffer [0] = iter; - OS.ATSFontIteratorRelease (buffer); - } - if (count == fds.length) return fds; - FontData[] result = new FontData[count]; - System.arraycopy(fds, 0, result, 0, count); - return result; -} - -Point getScreenDPI() { - int gdevice = OS.GetMainDevice(); - int[] ptr = new int[1]; - OS.memmove(ptr, gdevice, 4); - GDevice device = new GDevice(); - OS.memmove(device, ptr[0], GDevice.sizeof); - OS.memmove(ptr, device.gdPMap, 4); - PixMap pixmap = new PixMap(); - OS.memmove(pixmap, ptr[0], PixMap.sizeof); - return new Point (OS.Fix2Long (pixmap.hRes), OS.Fix2Long (pixmap.vRes)); -} - -/** - * Returns the matching standard color for the given - * constant, which should be one of the color constants - * specified in class <code>SWT</code>. Any value other - * than one of the SWT color constants which is passed - * in will result in the color black. This color should - * not be freed because it was allocated by the system, - * not the application. - * - * @param id the color constant - * @return the matching color - * - * @exception SWTException <ul> - * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see SWT - */ -public Color getSystemColor (int id) { - checkDevice (); - switch (id) { - case SWT.COLOR_BLACK: return COLOR_BLACK; - case SWT.COLOR_DARK_RED: return COLOR_DARK_RED; - case SWT.COLOR_DARK_GREEN: return COLOR_DARK_GREEN; - case SWT.COLOR_DARK_YELLOW: return COLOR_DARK_YELLOW; - case SWT.COLOR_DARK_BLUE: return COLOR_DARK_BLUE; - case SWT.COLOR_DARK_MAGENTA: return COLOR_DARK_MAGENTA; - case SWT.COLOR_DARK_CYAN: return COLOR_DARK_CYAN; - case SWT.COLOR_GRAY: return COLOR_GRAY; - case SWT.COLOR_DARK_GRAY: return COLOR_DARK_GRAY; - case SWT.COLOR_RED: return COLOR_RED; - case SWT.COLOR_GREEN: return COLOR_GREEN; - case SWT.COLOR_YELLOW: return COLOR_YELLOW; - case SWT.COLOR_BLUE: return COLOR_BLUE; - case SWT.COLOR_MAGENTA: return COLOR_MAGENTA; - case SWT.COLOR_CYAN: return COLOR_CYAN; - case SWT.COLOR_WHITE: return COLOR_WHITE; - } - return COLOR_BLACK; -} - -/** - * Returns a reasonable font for applications to use. - * On some platforms, this will match the "default font" - * or "system font" if such can be found. This font - * should not be freed because it was allocated by the - * system, not the application. - * <p> - * Typically, applications which want the default look - * should simply not set the font on the widgets they - * create. Widgets are always created with the correct - * default font for the class of user-interface component - * they represent. - * </p> - * - * @return a font - * - * @exception SWTException <ul> - * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public Font getSystemFont () { - checkDevice (); - return systemFont; -} - -/** - * Returns <code>true</code> if the underlying window system prints out - * warning messages on the console, and <code>setWarnings</code> - * had previously been called with <code>true</code>. - * - * @return <code>true</code>if warnings are being handled, and <code>false</code> otherwise - * - * @exception SWTException <ul> - * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public boolean getWarnings () { - checkDevice (); - return warnings; -} - -/** - * Initializes any internal resources needed by the - * device. - * <p> - * This method is called after <code>create</code>. - * </p><p> - * If subclasses reimplement this method, they must - * call the <code>super</code> implementation. - * </p> - * - * @see #create - */ -protected void init () { - colorspace = OS.CGColorSpaceCreateDeviceRGB(); - if (colorspace == 0) SWT.error(SWT.ERROR_NO_HANDLES); - - releaseCallback = new Callback (this, "releaseProc", 3); - releaseProc = releaseCallback.getAddress (); - if (releaseProc == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS); - - /* Create the standard colors */ - COLOR_BLACK = new Color (this, 0,0,0); - COLOR_DARK_RED = new Color (this, 0x80,0,0); - COLOR_DARK_GREEN = new Color (this, 0,0x80,0); - COLOR_DARK_YELLOW = new Color (this, 0x80,0x80,0); - COLOR_DARK_BLUE = new Color (this, 0,0,0x80); - COLOR_DARK_MAGENTA = new Color (this, 0x80,0,0x80); - COLOR_DARK_CYAN = new Color (this, 0,0x80,0x80); - COLOR_GRAY = new Color (this, 0xC0,0xC0,0xC0); - COLOR_DARK_GRAY = new Color (this, 0x80,0x80,0x80); - COLOR_RED = new Color (this, 0xFF,0,0); - COLOR_GREEN = new Color (this, 0,0xFF,0); - COLOR_YELLOW = new Color (this, 0xFF,0xFF,0); - COLOR_BLUE = new Color (this, 0,0,0xFF); - COLOR_MAGENTA = new Color (this, 0xFF,0,0xFF); - COLOR_CYAN = new Color (this, 0,0xFF,0xFF); - COLOR_WHITE = new Color (this, 0xFF,0xFF,0xFF); - - /* Initialize the system font slot */ - //TEMPORARY CODE - boolean smallFonts = System.getProperty("org.eclipse.swt.internal.carbon.smallFonts") != null; - byte [] family = new byte [256]; - short [] size = new short [1]; - byte [] style = new byte [1]; - int themeFont = smallFonts ? OS.kThemeSmallSystemFont : OS.kThemeSystemFont; - OS.GetThemeFont ((short) themeFont, (short) OS.smSystemScript, family, size, style); - short id = OS.FMGetFontFamilyFromName (family); - int [] font = new int [1]; - OS.FMGetFontFromFontFamilyInstance (id, style [0], font, null); - Point dpi = this.dpi = getDPI(), screenDPI = getScreenDPI(); - systemFont = Font.carbon_new (this, OS.FMGetATSFontRefFromFont (font [0]), style [0], size [0] * dpi.y / screenDPI.y); -} - -/** - * Invokes platform specific functionality to allocate a new GC handle. - * <p> - * <b>IMPORTANT:</b> This method is <em>not</em> part of the public - * API for <code>Device</code>. It is marked public only so that it - * can be shared within the packages provided by SWT. It is not - * available on all platforms, and should never be called from - * application code. - * </p> - * - * @param data the platform specific GC data - * @return the platform specific GC handle - */ -public abstract int internal_new_GC (GCData data); - -/** - * Invokes platform specific functionality to dispose a GC handle. - * <p> - * <b>IMPORTANT:</b> This method is <em>not</em> part of the public - * API for <code>Device</code>. It is marked public only so that it - * can be shared within the packages provided by SWT. It is not - * available on all platforms, and should never be called from - * application code. - * </p> - * - * @param hDC the platform specific GC handle - * @param data the platform specific GC data - */ -public abstract void internal_dispose_GC (int handle, GCData data); - -/** - * Returns <code>true</code> if the device has been disposed, - * and <code>false</code> otherwise. - * <p> - * This method gets the dispose state for the device. - * When a device has been disposed, it is an error to - * invoke any other method using the device. - * - * @return <code>true</code> when the device is disposed and <code>false</code> otherwise - */ -public boolean isDisposed () { - synchronized (Device.class) { - return disposed; - } -} - -/** - * Loads the font specified by a file. The font will be - * present in the list of fonts available to the application. - * - * @param path the font file path - * @return whether the font was successfully loaded - * - * @exception SWTException <ul> - * <li>ERROR_NULL_ARGUMENT - if path is null</li> - * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see Font - * - * @since 3.3 - */ -public boolean loadFont (String path) { - checkDevice(); - if (path == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - boolean result = false; - char [] chars = new char [path.length ()]; - path.getChars (0, chars.length, chars, 0); - int str = OS.CFStringCreateWithCharacters (OS.kCFAllocatorDefault, chars, chars.length); - if (str != 0) { - int url = OS.CFURLCreateWithFileSystemPath (OS.kCFAllocatorDefault, str, OS.kCFURLPOSIXPathStyle, false); - if (url != 0) { - byte [] fsRef = new byte [80]; - if (OS.CFURLGetFSRef (url, fsRef)) { - byte [] fsSpec = new byte [70]; - if (OS.FSGetCatalogInfo (fsRef, 0, null, null, fsSpec, null) == OS.noErr) { - int [] container = new int [1]; - result = OS.ATSFontActivateFromFileSpecification (fsSpec, OS.kATSFontContextLocal, OS.kATSFontFormatUnspecified, 0, OS.kATSOptionFlagsDefault, container) == OS.noErr; - } - } - OS.CFRelease (url); - } - OS.CFRelease (str); - } - return result; -} - -void new_Object (Object object) { - synchronized (trackingLock) { - for (int i=0; i<objects.length; i++) { - if (objects [i] == null) { - objects [i] = object; - errors [i] = new Error (); - return; - } - } - Object [] newObjects = new Object [objects.length + 128]; - System.arraycopy (objects, 0, newObjects, 0, objects.length); - newObjects [objects.length] = object; - objects = newObjects; - Error [] newErrors = new Error [errors.length + 128]; - System.arraycopy (errors, 0, newErrors, 0, errors.length); - newErrors [errors.length] = new Error (); - errors = newErrors; - } -} - -/** - * Releases any internal resources back to the operating - * system and clears all fields except the device handle. - * <p> - * When a device is destroyed, resources that were acquired - * on behalf of the programmer need to be returned to the - * operating system. For example, if the device allocated a - * font to be used as the system font, this font would be - * freed in <code>release</code>. Also,to assist the garbage - * collector and minimize the amount of memory that is not - * reclaimed when the programmer keeps a reference to a - * disposed device, all fields except the handle are zero'd. - * The handle is needed by <code>destroy</code>. - * </p> - * This method is called before <code>destroy</code>. - * </p><p> - * If subclasses reimplement this method, they must - * call the <code>super</code> implementation. - * </p> - * - * @see #dispose - * @see #destroy - */ -protected void release () { - if (releaseCallback != null) releaseCallback.dispose (); - if (drawPatternCallback != null) drawPatternCallback.dispose(); - if (axialShadingCallback != null) axialShadingCallback.dispose(); - releaseCallback = axialShadingCallback = drawPatternCallback = null; - releaseProc = axialShadingProc = drawPatternProc = 0; - - OS.CGColorSpaceRelease(colorspace); - colorspace = 0; - - if (COLOR_BLACK != null) COLOR_BLACK.dispose(); - if (COLOR_DARK_RED != null) COLOR_DARK_RED.dispose(); - if (COLOR_DARK_GREEN != null) COLOR_DARK_GREEN.dispose(); - if (COLOR_DARK_YELLOW != null) COLOR_DARK_YELLOW.dispose(); - if (COLOR_DARK_BLUE != null) COLOR_DARK_BLUE.dispose(); - if (COLOR_DARK_MAGENTA != null) COLOR_DARK_MAGENTA.dispose(); - if (COLOR_DARK_CYAN != null) COLOR_DARK_CYAN.dispose(); - if (COLOR_GRAY != null) COLOR_GRAY.dispose(); - if (COLOR_DARK_GRAY != null) COLOR_DARK_GRAY.dispose(); - if (COLOR_RED != null) COLOR_RED.dispose(); - if (COLOR_GREEN != null) COLOR_GREEN.dispose(); - if (COLOR_YELLOW != null) COLOR_YELLOW.dispose(); - if (COLOR_BLUE != null) COLOR_BLUE.dispose(); - if (COLOR_MAGENTA != null) COLOR_MAGENTA.dispose(); - if (COLOR_CYAN != null) COLOR_CYAN.dispose(); - if (COLOR_WHITE != null) COLOR_WHITE.dispose(); - COLOR_BLACK = COLOR_DARK_RED = COLOR_DARK_GREEN = COLOR_DARK_YELLOW = COLOR_DARK_BLUE = - COLOR_DARK_MAGENTA = COLOR_DARK_CYAN = COLOR_GRAY = COLOR_DARK_GRAY = COLOR_RED = - COLOR_GREEN = COLOR_YELLOW = COLOR_BLUE = COLOR_MAGENTA = COLOR_CYAN = COLOR_WHITE = null; -} - -int releaseProc (int info, int data, int size) { - OS.DisposePtr(data); - return 0; -} - -/** - * If the underlying window system supports printing warning messages - * to the console, setting warnings to <code>false</code> prevents these - * messages from being printed. If the argument is <code>true</code> then - * message printing is not blocked. - * - * @param warnings <code>true</code>if warnings should be printed, and <code>false</code> otherwise - * - * @exception SWTException <ul> - * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void setWarnings (boolean warnings) { - checkDevice (); - this.warnings = warnings; -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/DeviceData.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/DeviceData.java deleted file mode 100644 index 9b95c99718..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/DeviceData.java +++ /dev/null @@ -1,23 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2005 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.swt.graphics; - - -public class DeviceData { - /* - * Debug fields - may not be honoured - * on some SWT platforms. - */ - public boolean debug; - public boolean tracking; - public Error [] errors; - public Object [] objects; -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Font.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Font.java deleted file mode 100644 index b9bb11f18d..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Font.java +++ /dev/null @@ -1,427 +0,0 @@ -/******************************************************************************* - * 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.swt.graphics; - - -import org.eclipse.swt.internal.carbon.*; -import org.eclipse.swt.*; - -/** - * Instances of this class manage operating system resources that - * define how text looks when it is displayed. Fonts may be constructed - * by providing a device and either name, size and style information - * or a <code>FontData</code> object which encapsulates this data. - * <p> - * Application code must explicitly invoke the <code>Font.dispose()</code> - * method to release the operating system resources managed by each instance - * when those instances are no longer required. - * </p> - * - * @see FontData - * @see <a href="http://www.eclipse.org/swt/snippets/#font">Font snippets</a> - * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Examples: GraphicsExample, PaintExample</a> - * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> - */ -public final class Font extends Resource { - - /** - * the handle to the OS font resource - * (Warning: This field is platform dependent) - * <p> - * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT - * public API. It is marked public only so that it can be shared - * within the packages provided by SWT. It is not available on all - * platforms and should never be accessed from application code. - * </p> - */ - public int handle; - - /** - * the style to the OS font (a FMFontStyle) - * (Warning: This field is platform dependent) - * <p> - * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT - * public API. It is marked public only so that it can be shared - * within the packages provided by SWT. It is not available on all - * platforms and should never be accessed from application code. - * </p> - */ - public short style; - - /** - * the size to the OS font - * (Warning: This field is platform dependent) - * <p> - * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT - * public API. It is marked public only so that it can be shared - * within the packages provided by SWT. It is not available on all - * platforms and should never be accessed from application code. - * </p> - */ - public float size; - - /** - * the ATSUI style for the OS font - * (Warning: This field is platform dependent) - * <p> - * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT - * public API. It is marked public only so that it can be shared - * within the packages provided by SWT. It is not available on all - * platforms and should never be accessed from application code. - * </p> - */ - public int atsuiStyle; - -Font(Device device) { - super(device); -} - -/** - * Constructs a new font given a device and font data - * which describes the desired font's appearance. - * <p> - * You must dispose the font when it is no longer required. - * </p> - * - * @param device the device to create the font on - * @param fd the FontData that describes the desired font (must not be null) - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li> - * <li>ERROR_NULL_ARGUMENT - if the fd argument is null</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES - if a font could not be created from the given font data</li> - * </ul> - */ -public Font(Device device, FontData fd) { - super(device); - if (fd == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - init(fd.getName(), fd.getHeightF(), fd.getStyle(), fd.atsName); - init(); -} - -/** - * Constructs a new font given a device and an array - * of font data which describes the desired font's - * appearance. - * <p> - * You must dispose the font when it is no longer required. - * </p> - * - * @param device the device to create the font on - * @param fds the array of FontData that describes the desired font (must not be null) - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li> - * <li>ERROR_NULL_ARGUMENT - if the fds argument is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the length of fds is zero</li> - * <li>ERROR_NULL_ARGUMENT - if any fd in the array is null</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES - if a font could not be created from the given font data</li> - * </ul> - * - * @since 2.1 - */ -public Font(Device device, FontData[] fds) { - super(device); - if (fds == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (fds.length == 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - for (int i=0; i<fds.length; i++) { - if (fds[i] == null) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - FontData fd = fds[0]; - init(fd.getName(), fd.getHeightF(), fd.getStyle(), fd.atsName); - init(); -} - -/** - * Constructs a new font given a device, a font name, - * the height of the desired font in points, and a font - * style. - * <p> - * You must dispose the font when it is no longer required. - * </p> - * - * @param device the device to create the font on - * @param name the name of the font (must not be null) - * @param height the font height in points - * @param style a bit or combination of NORMAL, BOLD, ITALIC - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li> - * <li>ERROR_NULL_ARGUMENT - if the name argument is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the height is negative</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES - if a font could not be created from the given arguments</li> - * </ul> - */ -public Font(Device device, String name, int height, int style) { - super(device); - init(name, height, style, null); - init(); -} - -/*public*/ Font(Device device, String name, float height, int style) { - super(device); - init(name, height, style, null); - init(); -} - -int createStyle () { - int[] buffer = new int[1]; - OS.ATSUCreateStyle(buffer); - if (buffer[0] == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int atsuStyle = buffer[0]; - - boolean synthesize = style != 0; - int ptr = OS.NewPtr(8 + (synthesize ? 8 : 0)); - OS.memmove(ptr, new int[]{OS.FMGetFontFromATSFontRef(handle)}, 4); - OS.memmove(ptr + 4, new int[]{OS.X2Fix(size)}, 4); - int[] tags, sizes, values; - if (synthesize) { - OS.memmove(ptr + 8, new byte[]{(style & OS.bold) != 0 ? (byte)1 : 0}, 1); - OS.memmove(ptr + 9, new byte[]{(style & OS.italic) != 0 ? (byte)1 : 0}, 1); - tags = new int[]{OS.kATSUFontTag, OS.kATSUSizeTag, OS.kATSUQDBoldfaceTag, OS.kATSUQDItalicTag}; - sizes = new int[]{4, 4, 1, 1}; - values = new int[]{ptr, ptr + 4, ptr + 8, ptr + 9}; - } else { - tags = new int[]{OS.kATSUFontTag, OS.kATSUSizeTag}; - sizes = new int[]{4, 4}; - values = new int[]{ptr, ptr + 4}; - } - OS.ATSUSetAttributes(atsuStyle, tags.length, tags, sizes, values); - OS.DisposePtr(ptr); - - short[] types = { - (short)OS.kLigaturesType, - (short)OS.kLigaturesType, - (short)OS.kLigaturesType, - (short)OS.kLigaturesType, - (short)OS.kLigaturesType, - (short)OS.kLigaturesType, - (short)OS.kLigaturesType, - (short)OS.kLigaturesType, - }; - short[] selectors = { - (short)OS.kRequiredLigaturesOffSelector, - (short)OS.kCommonLigaturesOffSelector, - (short)OS.kRareLigaturesOffSelector, - (short)OS.kLogosOffSelector, - (short)OS.kRebusPicturesOffSelector, - (short)OS.kDiphthongLigaturesOffSelector, - (short)OS.kSquaredLigaturesOffSelector, - (short)OS.kAbbrevSquaredLigaturesOffSelector, - (short)OS.kSymbolLigaturesOffSelector, - }; - OS.ATSUSetFontFeatures(atsuStyle, types.length, types, selectors); - return atsuStyle; -} - -void destroy() { - if (handle == 0) return; - handle = 0; - if (atsuiStyle != 0) OS.ATSUDisposeStyle(atsuiStyle); - atsuiStyle = 0; -} - -/** - * Compares the argument to the receiver, and returns true - * if they represent the <em>same</em> object using a class - * specific comparison. - * - * @param object the object to compare with this object - * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise - * - * @see #hashCode - */ -public boolean equals(Object object) { - if (object == this) return true; - if (!(object instanceof Font)) return false; - Font font = (Font)object; - return handle == font.handle && size == font.size; -} - -/** - * Returns an array of <code>FontData</code>s representing the receiver. - * On Windows, only one FontData will be returned per font. On X however, - * a <code>Font</code> object <em>may</em> be composed of multiple X - * fonts. To support this case, we return an array of font data objects. - * - * @return an array of font data objects describing the receiver - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public FontData[] getFontData() { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - int[] buffer = new int[1]; - OS.ATSFontGetName(handle, 0, buffer); - CFRange range = new CFRange(); - range.length = OS.CFStringGetLength(buffer[0]); - char [] chars = new char[range.length]; - OS.CFStringGetCharacters(buffer[0], range, chars); - OS.CFRelease(buffer[0]); - String atsName = new String(chars); - int platformCode = OS.kFontUnicodePlatform, encoding = OS.kCFStringEncodingUnicode; - if (OS.ATSUFindFontName(handle, OS.kFontFamilyName, platformCode, OS.kFontNoScriptCode, OS.kFontNoLanguageCode, 0, null, buffer, null) != OS.noErr) { - platformCode = OS.kFontNoPlatformCode; - encoding = OS.kCFStringEncodingMacRoman; - OS.ATSUFindFontName (handle, OS.kFontFamilyName, platformCode, OS.kFontNoScriptCode, OS.kFontNoLanguageCode, 0, null, buffer, null); - } - byte[] bytes = new byte[buffer[0]]; - OS.ATSUFindFontName(handle, OS.kFontFamilyName, platformCode, OS.kFontNoScriptCode, OS.kFontNoLanguageCode, bytes.length, bytes, buffer, null); - String name = ""; - int ptr = OS.CFStringCreateWithBytes(0, bytes, bytes.length, encoding, false); - if (ptr != 0) { - range.length = OS.CFStringGetLength(ptr); - if (range.length != 0) { - chars = new char[range.length]; - OS.CFStringGetCharacters(ptr, range, chars); - name = new String(chars); - } - OS.CFRelease(ptr); - } - int style = 0; - if ((this.style & OS.italic) != 0) style |= SWT.ITALIC; - if ((this.style & OS.bold) != 0) style |= SWT.BOLD; - if (atsName.indexOf("Italic") != -1) style |= SWT.ITALIC; - if (atsName.indexOf("Bold") != -1) style |= SWT.BOLD; - Point dpi = device.dpi, screenDPI = device.getScreenDPI(); - FontData data = new FontData(name, size * screenDPI.y / dpi.y, style); - data.atsName = atsName; - return new FontData[]{data}; -} - -/** - * Invokes platform specific functionality to allocate a new font. - * <p> - * <b>IMPORTANT:</b> This method is <em>not</em> part of the public - * API for <code>Font</code>. It is marked public only so that it - * can be shared within the packages provided by SWT. It is not - * available on all platforms, and should never be called from - * application code. - * </p> - * - * @param device the device on which to allocate the color - * @param handle the handle for the font - * @param style the style for the font - * @param size the size for the font - * - * @private - */ -public static Font carbon_new(Device device, int handle, short style, float size) { - Font font = new Font(device); - font.handle = handle; - font.style = style; - font.size = size; - return font; -} - -/** - * Returns an integer hash code for the receiver. Any two - * objects that return <code>true</code> when passed to - * <code>equals</code> must return the same value for this - * method. - * - * @return the receiver's hash - * - * @see #equals - */ -public int hashCode() { - return handle; -} - -void init(String name, float height, int style, String atsName) { - if (name == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (height < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - int font = 0; - if (atsName != null) { - int ptr = createCFString(atsName); - if (ptr != 0) { - font = OS.ATSFontFindFromName(ptr, OS.kATSOptionFlagsDefault); - OS.CFRelease(ptr); - } - } else { - atsName = name; - if ((style & SWT.BOLD) != 0) atsName += " Bold"; - if ((style & SWT.ITALIC) != 0) atsName += " Italic"; - int ptr = createCFString(atsName); - if (ptr != 0) { - font = OS.ATSFontFindFromName(ptr, OS.kATSOptionFlagsDefault); - OS.CFRelease(ptr); - } - if (font == 0 && (style & SWT.ITALIC) != 0) { - this.style |= OS.italic; - atsName = name; - if ((style & SWT.BOLD) != 0) atsName += " Bold"; - ptr = createCFString(atsName); - if (ptr != 0) { - font = OS.ATSFontFindFromName(ptr, OS.kATSOptionFlagsDefault); - OS.CFRelease(ptr); - } - } - if (font == 0 && (style & SWT.BOLD) != 0) { - this.style |= OS.bold; - atsName = name; - ptr = createCFString(atsName); - if (ptr != 0) { - font = OS.ATSFontFindFromName(ptr, OS.kATSOptionFlagsDefault); - OS.CFRelease(ptr); - } - } - } - Point dpi = device.dpi, screenDPI = device.getScreenDPI(); - this.size = height * dpi.y / screenDPI.y; - if (font == 0) { - Font systemFont = device.systemFont; - this.handle = systemFont.handle; - } else { - this.handle = font; - } - this.atsuiStyle = createStyle(); -} - -int createCFString(String str) { - char[] chars = new char[str.length()]; - str.getChars(0, chars.length, chars, 0); - return OS.CFStringCreateWithCharacters(OS.kCFAllocatorDefault, chars, chars.length); -} - -/** - * Returns <code>true</code> if the font has been disposed, - * and <code>false</code> otherwise. - * <p> - * This method gets the dispose state for the font. - * When a font has been disposed, it is an error to - * invoke any other method using the font. - * - * @return <code>true</code> when the font is disposed and <code>false</code> otherwise - */ -public boolean isDisposed() { - return handle == 0; -} - -/** - * Returns a string containing a concise, human-readable - * description of the receiver. - * - * @return a string representation of the receiver - */ -public String toString () { - if (isDisposed()) return "Font {*DISPOSED*}"; - return "Font {" + handle + "}"; -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/FontData.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/FontData.java deleted file mode 100644 index 67d8aa9c60..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/FontData.java +++ /dev/null @@ -1,447 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2009 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.swt.graphics; - - -import org.eclipse.swt.*; - -/** - * Instances of this class describe operating system fonts. - * <p> - * For platform-independent behaviour, use the get and set methods - * corresponding to the following properties: - * <dl> - * <dt>height</dt><dd>the height of the font in points</dd> - * <dt>name</dt><dd>the face name of the font, which may include the foundry</dd> - * <dt>style</dt><dd>A bitwise combination of NORMAL, ITALIC and BOLD</dd> - * </dl> - * If extra, platform-dependent functionality is required: - * <ul> - * <li>On <em>Windows</em>, the data member of the <code>FontData</code> - * corresponds to a Windows <code>LOGFONT</code> structure whose fields - * may be retrieved and modified.</li> - * <li>On <em>X</em>, the fields of the <code>FontData</code> correspond - * to the entries in the font's XLFD name and may be retrieved and modified. - * </ul> - * Application code does <em>not</em> need to explicitly release the - * resources managed by each instance when those instances are no longer - * required, and thus no <code>dispose()</code> method is provided. - * - * @see Font - * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> - */ -public final class FontData { - /** - * the font name - * (Warning: This field is platform dependent) - * <p> - * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT - * public API. It is marked public only so that it can be shared - * within the packages provided by SWT. It is not available on all - * platforms and should never be accessed from application code. - * </p> - */ - public String name; - - /** - * The height of the font data in points - * (Warning: This field is platform dependent) - * <p> - * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT - * public API. It is marked public only so that it can be shared - * within the packages provided by SWT. It is not available on all - * platforms and should never be accessed from application code. - * </p> - */ - public float height; - - /** - * the font style - * (Warning: This field is platform dependent) - * <p> - * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT - * public API. It is marked public only so that it can be shared - * within the packages provided by SWT. It is not available on all - * platforms and should never be accessed from application code. - * </p> - */ - public int style; - - /** - * the ATS font name - * (Warning: This field is platform dependent) - * <p> - * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT - * public API. It is marked public only so that it can be shared - * within the packages provided by SWT. It is not available on all - * platforms and should never be accessed from application code. - * </p> - */ - public String atsName; - - /** - * The locales of the font - */ - String lang, country, variant; - -/** - * Constructs a new uninitialized font data. - */ -public FontData () { - this("", 12, SWT.NORMAL); -} - -/** - * Constructs a new FontData given a string representation - * in the form generated by the <code>FontData.toString</code> - * method. - * <p> - * Note that the representation varies between platforms, - * and a FontData can only be created from a string that was - * generated on the same platform. - * </p> - * - * @param string the string representation of a <code>FontData</code> (must not be null) - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the argument is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the argument does not represent a valid description</li> - * </ul> - * - * @see #toString - */ -public FontData(String string) { - if (string == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - int start = 0; - int end = string.indexOf('|'); - if (end == -1) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - String version1 = string.substring(start, end); - try { - if (Integer.parseInt(version1) != 1) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } catch (NumberFormatException e) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - - start = end + 1; - end = string.indexOf('|', start); - if (end == -1) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - String name = string.substring(start, end); - - start = end + 1; - end = string.indexOf('|', start); - if (end == -1) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - float height = 0; - try { - height = Float.parseFloat(string.substring(start, end)); - } catch (NumberFormatException e) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - - start = end + 1; - end = string.indexOf('|', start); - if (end == -1) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - int style = 0; - try { - style = Integer.parseInt(string.substring(start, end)); - } catch (NumberFormatException e) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - - start = end + 1; - end = string.indexOf('|', start); - setName(name); - setHeight(height); - setStyle(style); - if (end == -1) return; - String platform = string.substring(start, end); - - start = end + 1; - end = string.indexOf('|', start); - if (end == -1) return; - String version2 = string.substring(start, end); - - if (platform.equals("CARBON") && version2.equals("1")) { - start = end + 1; - end = string.length(); - if (start < end) atsName = string.substring(start, end); - } -} - -/** - * Constructs a new font data given a font name, - * the height of the desired font in points, - * and a font style. - * - * @param name the name of the font (must not be null) - * @param height the font height in points - * @param style a bit or combination of NORMAL, BOLD, ITALIC - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - when the font name is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the height is negative</li> - * </ul> - */ -public FontData(String name, int height, int style) { - setName(name); - setHeight(height); - setStyle(style); -} - -/*public*/ FontData(String name, float height, int style) { - setName(name); - setHeight(height); - setStyle(style); -} - -/** - * Compares the argument to the receiver, and returns true - * if they represent the <em>same</em> object using a class - * specific comparison. - * - * @param object the object to compare with this object - * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise - * - * @see #hashCode - */ -public boolean equals (Object object) { - if (object == this) return true; - if (!(object instanceof FontData)) return false; - FontData data = (FontData)object; - return name.equals(data.name) && height == data.height && style == data.style; -} - -/** - * Returns the height of the receiver in points. - * - * @return the height of this FontData - * - * @see #setHeight(int) - */ -public int getHeight() { - return (int)height; -} - -/*public*/ float getHeightF() { - return height; -} - -/** - * Returns the locale of the receiver. - * <p> - * The locale determines which platform character set this - * font is going to use. Widgets and graphics operations that - * use this font will convert UNICODE strings to the platform - * character set of the specified locale. - * </p> - * <p> - * On platforms where there are multiple character sets for a - * given language/country locale, the variant portion of the - * locale will determine the character set. - * </p> - * - * @return the <code>String</code> representing a Locale object - * @since 3.0 - */ -public String getLocale () { - StringBuffer buffer = new StringBuffer (); - char sep = '_'; - if (lang != null) { - buffer.append (lang); - buffer.append (sep); - } - if (country != null) { - buffer.append (country); - buffer.append (sep); - } - if (variant != null) { - buffer.append (variant); - } - - String result = buffer.toString (); - int length = result.length (); - if (length > 0) { - if (result.charAt (length - 1) == sep) { - result = result.substring (0, length - 1); - } - } - return result; -} - -/** - * Returns the name of the receiver. - * On platforms that support font foundries, the return value will - * be the foundry followed by a dash ("-") followed by the face name. - * - * @return the name of this <code>FontData</code> - * - * @see #setName - */ -public String getName() { - return name; -} - -/** - * Returns the style of the receiver which is a bitwise OR of - * one or more of the <code>SWT</code> constants NORMAL, BOLD - * and ITALIC. - * - * @return the style of this <code>FontData</code> - * - * @see #setStyle - */ -public int getStyle() { - return style; -} - -/** - * Returns an integer hash code for the receiver. Any two - * objects that return <code>true</code> when passed to - * <code>equals</code> must return the same value for this - * method. - * - * @return the receiver's hash - * - * @see #equals - */ -public int hashCode () { - return name.hashCode() ^ getHeight() ^ style; -} - -/** - * Sets the height of the receiver. The parameter is - * specified in terms of points, where a point is one - * seventy-second of an inch. - * - * @param height the height of the <code>FontData</code> - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the height is negative</li> - * </ul> - * - * @see #getHeight - */ -public void setHeight(int height) { - if (height < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - this.height = height; -} - -/*public*/ void setHeight(float height) { - if (height < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - this.height = height; -} - -/** - * Sets the locale of the receiver. - * <p> - * The locale determines which platform character set this - * font is going to use. Widgets and graphics operations that - * use this font will convert UNICODE strings to the platform - * character set of the specified locale. - * </p> - * <p> - * On platforms where there are multiple character sets for a - * given language/country locale, the variant portion of the - * locale will determine the character set. - * </p> - * - * @param locale the <code>String</code> representing a Locale object - * @see java.util.Locale#toString - */ -public void setLocale(String locale) { - lang = country = variant = null; - if (locale != null) { - char sep = '_'; - int length = locale.length(); - int firstSep, secondSep; - - firstSep = locale.indexOf(sep); - if (firstSep == -1) { - firstSep = secondSep = length; - } else { - secondSep = locale.indexOf(sep, firstSep + 1); - if (secondSep == -1) secondSep = length; - } - if (firstSep > 0) lang = locale.substring(0, firstSep); - if (secondSep > firstSep + 1) country = locale.substring(firstSep + 1, secondSep); - if (length > secondSep + 1) variant = locale.substring(secondSep + 1); - } -} - -/** - * Sets the name of the receiver. - * <p> - * Some platforms support font foundries. On these platforms, the name - * of the font specified in setName() may have one of the following forms: - * <ol> - * <li>a face name (for example, "courier")</li> - * <li>a foundry followed by a dash ("-") followed by a face name (for example, "adobe-courier")</li> - * </ol> - * In either case, the name returned from getName() will include the - * foundry. - * </p> - * <p> - * On platforms that do not support font foundries, only the face name - * (for example, "courier") is used in <code>setName()</code> and - * <code>getName()</code>. - * </p> - * - * @param name the name of the font data (must not be null) - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - when the font name is null</li> - * </ul> - * - * @see #getName - */ -public void setName(String name) { - if (name == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - this.name = name; - atsName = null; -} - -/** - * Sets the style of the receiver to the argument which must - * be a bitwise OR of one or more of the <code>SWT</code> - * constants NORMAL, BOLD and ITALIC. All other style bits are - * ignored. - * - * @param style the new style for this <code>FontData</code> - * - * @see #getStyle - */ -public void setStyle(int style) { - this.style = style; - atsName = null; -} - -/** - * Returns a string representation of the receiver which is suitable - * for constructing an equivalent instance using the - * <code>FontData(String)</code> constructor. - * - * @return a string representation of the FontData - * - * @see FontData - */ -public String toString() { - StringBuffer buffer = new StringBuffer(128); - buffer.append("1|"); - buffer.append(getName()); - buffer.append("|"); - buffer.append(getHeightF()); - buffer.append("|"); - buffer.append(getStyle()); - buffer.append("|"); - buffer.append("CARBON|1|"); - if (atsName != null) buffer.append(atsName); - return buffer.toString(); -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/FontMetrics.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/FontMetrics.java deleted file mode 100644 index f3fc1ca48e..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/FontMetrics.java +++ /dev/null @@ -1,133 +0,0 @@ -/******************************************************************************* - * 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.swt.graphics; - - -/** - * Instances of this class provide measurement information - * about fonts including ascent, descent, height, leading - * space between rows, and average character width. - * <code>FontMetrics</code> are obtained from <code>GC</code>s - * using the <code>getFontMetrics()</code> method. - * - * @see GC#getFontMetrics - * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> - */ -public final class FontMetrics { - int ascent, descent, averageCharWidth, leading, height; - -FontMetrics() { -} - -public static FontMetrics carbon_new(int ascent, int descent, int averageCharWidth, int leading, int height) { - FontMetrics fontMetrics = new FontMetrics(); - fontMetrics.ascent = ascent; - fontMetrics.descent = descent; - fontMetrics.averageCharWidth = averageCharWidth; - fontMetrics.leading = leading; - fontMetrics.height = height; - return fontMetrics; -} - -/** - * Compares the argument to the receiver, and returns true - * if they represent the <em>same</em> object using a class - * specific comparison. - * - * @param object the object to compare with this object - * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise - * - * @see #hashCode - */ -public boolean equals (Object object) { - if (object == this) return true; - if (!(object instanceof FontMetrics)) return false; - FontMetrics metrics = (FontMetrics)object; - return ascent == metrics.ascent && descent == metrics.descent && - averageCharWidth == metrics.averageCharWidth && leading == metrics.leading && - height == metrics.height; -} - -/** - * Returns the ascent of the font described by the receiver. A - * font's <em>ascent</em> is the distance from the baseline to the - * top of actual characters, not including any of the leading area, - * measured in pixels. - * - * @return the ascent of the font - */ -public int getAscent() { - return ascent; -} - -/** - * Returns the average character width, measured in pixels, - * of the font described by the receiver. - * - * @return the average character width of the font - */ -public int getAverageCharWidth() { - return averageCharWidth; -} - -/** - * Returns the descent of the font described by the receiver. A - * font's <em>descent</em> is the distance from the baseline to the - * bottom of actual characters, not including any of the leading area, - * measured in pixels. - * - * @return the descent of the font - */ -public int getDescent() { - return descent; -} - -/** - * Returns the height of the font described by the receiver, - * measured in pixels. A font's <em>height</em> is the sum of - * its ascent, descent and leading area. - * - * @return the height of the font - * - * @see #getAscent - * @see #getDescent - * @see #getLeading - */ -public int getHeight() { - return height; -} - -/** - * Returns the leading area of the font described by the - * receiver. A font's <em>leading area</em> is the space - * above its ascent which may include accents or other marks. - * - * @return the leading space of the font - */ -public int getLeading() { - return leading; -} - -/** - * Returns an integer hash code for the receiver. Any two - * objects that return <code>true</code> when passed to - * <code>equals</code> must return the same value for this - * method. - * - * @return the receiver's hash - * - * @see #equals - */ -public int hashCode() { - return ascent ^ descent ^ averageCharWidth ^ leading ^ height; -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/GC.java deleted file mode 100644 index 58e49e9731..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/GC.java +++ /dev/null @@ -1,3674 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2009 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.swt.graphics; - -import org.eclipse.swt.internal.*; -import org.eclipse.swt.internal.carbon.*; -import org.eclipse.swt.*; - -/** - * Class <code>GC</code> is where all of the drawing capabilities that are - * supported by SWT are located. Instances are used to draw on either an - * <code>Image</code>, a <code>Control</code>, or directly on a <code>Display</code>. - * <dl> - * <dt><b>Styles:</b></dt> - * <dd>LEFT_TO_RIGHT, RIGHT_TO_LEFT</dd> - * </dl> - * - * <p> - * The SWT drawing coordinate system is the two-dimensional space with the origin - * (0,0) at the top left corner of the drawing area and with (x,y) values increasing - * to the right and downward respectively. - * </p> - * - * <p> - * The result of drawing on an image that was created with an indexed - * palette using a color that is not in the palette is platform specific. - * Some platforms will match to the nearest color while other will draw - * the color itself. This happens because the allocated image might use - * a direct palette on platforms that do not support indexed palette. - * </p> - * - * <p> - * Application code must explicitly invoke the <code>GC.dispose()</code> - * method to release the operating system resources managed by each instance - * when those instances are no longer required. This is <em>particularly</em> - * important on Windows95 and Windows98 where the operating system has a limited - * number of device contexts available. - * </p> - * - * <p> - * Note: Only one of LEFT_TO_RIGHT and RIGHT_TO_LEFT may be specified. - * </p> - * - * @see org.eclipse.swt.events.PaintEvent - * @see <a href="http://www.eclipse.org/swt/snippets/#gc">GC snippets</a> - * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Examples: GraphicsExample, PaintExample</a> - * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> - */ -public final class GC extends Resource { - /** - * the handle to the OS device context - * (Warning: This field is platform dependent) - * <p> - * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT - * public API. It is marked public only so that it can be shared - * within the packages provided by SWT. It is not available on all - * platforms and should never be accessed from application code. - * </p> - */ - public int handle; - - Drawable drawable; - GCData data; - - static final int TAB_COUNT = 32; - - final static int FOREGROUND = 1 << 0; - final static int BACKGROUND = 1 << 1; - final static int FONT = 1 << 2; - final static int LINE_STYLE = 1 << 3; - final static int LINE_CAP = 1 << 4; - final static int LINE_JOIN = 1 << 5; - final static int LINE_WIDTH = 1 << 6; - final static int LINE_MITERLIMIT = 1 << 7; - final static int FOREGROUND_FILL = 1 << 8; - final static int DRAW_OFFSET = 1 << 9; - final static int DRAW = FOREGROUND | LINE_WIDTH | LINE_STYLE | LINE_CAP | LINE_JOIN | LINE_MITERLIMIT | DRAW_OFFSET; - final static int FILL = BACKGROUND; - - static final float[] LINE_DOT = new float[]{1, 1}; - static final float[] LINE_DASH = new float[]{3, 1}; - static final float[] LINE_DASHDOT = new float[]{3, 1, 1, 1}; - static final float[] LINE_DASHDOTDOT = new float[]{3, 1, 1, 1, 1, 1}; - static final float[] LINE_DOT_ZERO = new float[]{3, 3}; - static final float[] LINE_DASH_ZERO = new float[]{18, 6}; - static final float[] LINE_DASHDOT_ZERO = new float[]{9, 6, 3, 6}; - static final float[] LINE_DASHDOTDOT_ZERO = new float[]{9, 3, 3, 3, 3, 3}; - -GC() { -} - -/** - * Constructs a new instance of this class which has been - * configured to draw on the specified drawable. Sets the - * foreground color, background color and font in the GC - * to match those in the drawable. - * <p> - * You must dispose the graphics context when it is no longer required. - * </p> - * @param drawable the drawable to draw on - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the drawable is null</li> - * <li>ERROR_NULL_ARGUMENT - if there is no current device</li> - * <li>ERROR_INVALID_ARGUMENT - * - if the drawable is an image that is not a bitmap or an icon - * - if the drawable is an image or printer that is already selected - * into another graphics context</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES if a handle could not be obtained for GC creation</li> - * <li>ERROR_THREAD_INVALID_ACCESS if not called from the thread that created the drawable</li> - * </ul> - */ -public GC(Drawable drawable) { - this(drawable, 0); -} - -/** - * Constructs a new instance of this class which has been - * configured to draw on the specified drawable. Sets the - * foreground color, background color and font in the GC - * to match those in the drawable. - * <p> - * You must dispose the graphics context when it is no longer required. - * </p> - * - * @param drawable the drawable to draw on - * @param style the style of GC to construct - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the drawable is null</li> - * <li>ERROR_NULL_ARGUMENT - if there is no current device</li> - * <li>ERROR_INVALID_ARGUMENT - * - if the drawable is an image that is not a bitmap or an icon - * - if the drawable is an image or printer that is already selected - * into another graphics context</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES if a handle could not be obtained for GC creation</li> - * <li>ERROR_THREAD_INVALID_ACCESS if not called from the thread that created the drawable</li> - * </ul> - * - * @since 2.1.2 - */ -public GC(Drawable drawable, int style) { - if (drawable == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - GCData data = new GCData(); - data.style = checkStyle(style); - int gdkGC = drawable.internal_new_GC(data); - Device device = data.device; - if (device == null) device = Device.getDevice(); - if (device == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - this.device = data.device = device; - init(drawable, data, gdkGC); - init(); -} - -static int checkStyle (int style) { - if ((style & SWT.LEFT_TO_RIGHT) != 0) style &= ~SWT.RIGHT_TO_LEFT; - return style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT); -} - -/** - * Invokes platform specific functionality to allocate a new graphics context. - * <p> - * <b>IMPORTANT:</b> This method is <em>not</em> part of the public - * API for <code>GC</code>. It is marked public only so that it - * can be shared within the packages provided by SWT. It is not - * available on all platforms, and should never be called from - * application code. - * </p> - * - * @param drawable the Drawable for the receiver. - * @param data the data for the receiver. - * - * @return a new <code>GC</code> - * - * @private - */ -public static GC carbon_new(Drawable drawable, GCData data) { - GC gc = new GC(); - int context = drawable.internal_new_GC(data); - gc.device = data.device; - gc.init(drawable, data, context); - 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 SWT. 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(int context, GCData data) { - GC gc = new GC(); - gc.device = data.device; - gc.init(null, data, context); - return gc; -} - -void checkGC (int mask) { - int state = data.state; - if ((state & mask) == mask) return; - state = (state ^ mask) & mask; - data.state |= mask; - if ((state & FOREGROUND) != 0) { - Pattern pattern = data.foregroundPattern; - if (pattern != null) { - int colorspace = OS.CGColorSpaceCreatePattern(data.device.colorspace); - OS.CGContextSetStrokeColorSpace(handle, colorspace); - OS.CGColorSpaceRelease(colorspace); - if (data.forePattern == 0) data.forePattern = pattern.createPattern(handle); - OS.CGContextSetStrokePattern(handle, data.forePattern, data.foreground); - } else { - OS.CGContextSetStrokeColorSpace(handle, data.device.colorspace); - OS.CGContextSetStrokeColor(handle, data.foreground); - } - } - if ((state & FOREGROUND_FILL) != 0) { - Pattern pattern = data.foregroundPattern; - if (pattern != null) { - int colorspace = OS.CGColorSpaceCreatePattern(data.device.colorspace); - OS.CGContextSetFillColorSpace(handle, colorspace); - OS.CGColorSpaceRelease(colorspace); - if (data.forePattern == 0) data.forePattern = pattern.createPattern(handle); - OS.CGContextSetFillPattern(handle, data.forePattern, data.foreground); - } else { - OS.CGContextSetFillColorSpace(handle, data.device.colorspace); - OS.CGContextSetFillColor(handle, data.foreground); - } - data.state &= ~BACKGROUND; - } - if ((state & BACKGROUND) != 0) { - Pattern pattern = data.backgroundPattern; - if (pattern != null) { - int colorspace = OS.CGColorSpaceCreatePattern(data.device.colorspace); - OS.CGContextSetFillColorSpace(handle, colorspace); - OS.CGColorSpaceRelease(colorspace); - if (data.backPattern == 0) data.backPattern = pattern.createPattern(handle); - OS.CGContextSetFillPattern(handle, data.backPattern, data.background); - } else { - OS.CGContextSetFillColorSpace(handle, data.device.colorspace); - OS.CGContextSetFillColor(handle, data.background); - } - data.state &= ~FOREGROUND_FILL; - } - if ((state & FONT) != 0) { - setCGFont(); - } - if ((state & LINE_WIDTH) != 0) { - OS.CGContextSetLineWidth(handle, data.lineWidth == 0 ? 1 : data.lineWidth); - switch (data.lineStyle) { - case SWT.LINE_DOT: - case SWT.LINE_DASH: - case SWT.LINE_DASHDOT: - case SWT.LINE_DASHDOTDOT: - state |= LINE_STYLE; - } - } - if ((state & LINE_STYLE) != 0) { - float[] dashes = null; - float width = data.lineWidth; - switch (data.lineStyle) { - case SWT.LINE_SOLID: break; - case SWT.LINE_DASH: dashes = width != 0 ? LINE_DASH : LINE_DASH_ZERO; break; - case SWT.LINE_DOT: dashes = width != 0 ? LINE_DOT : LINE_DOT_ZERO; break; - case SWT.LINE_DASHDOT: dashes = width != 0 ? LINE_DASHDOT : LINE_DASHDOT_ZERO; break; - case SWT.LINE_DASHDOTDOT: dashes = width != 0 ? LINE_DASHDOTDOT : LINE_DASHDOTDOT_ZERO; break; - case SWT.LINE_CUSTOM: dashes = data.lineDashes; break; - } - if (dashes != null) { - float[] lengths = new float[dashes.length]; - for (int i = 0; i < lengths.length; i++) { - lengths[i] = width == 0 || data.lineStyle == SWT.LINE_CUSTOM ? dashes[i] : dashes[i] * width; - } - OS.CGContextSetLineDash(handle, data.lineDashesOffset, lengths, lengths.length); - } else { - OS.CGContextSetLineDash(handle, 0, null, 0); - } - } - if ((state & LINE_MITERLIMIT) != 0) { - OS.CGContextSetMiterLimit(handle, data.lineMiterLimit); - } - if ((state & LINE_JOIN) != 0) { - int joinStyle = 0; - switch (data.lineJoin) { - case SWT.JOIN_MITER: joinStyle = OS.kCGLineJoinMiter; break; - case SWT.JOIN_ROUND: joinStyle = OS.kCGLineJoinRound; break; - case SWT.JOIN_BEVEL: joinStyle = OS.kCGLineJoinBevel; break; - } - OS.CGContextSetLineJoin(handle, joinStyle); - } - if ((state & LINE_CAP) != 0) { - int capStyle = 0; - switch (data.lineCap) { - case SWT.CAP_ROUND: capStyle = OS.kCGLineCapRound; break; - case SWT.CAP_FLAT: capStyle = OS.kCGLineCapButt; break; - case SWT.CAP_SQUARE: capStyle = OS.kCGLineCapSquare; break; - } - OS.CGContextSetLineCap(handle, capStyle); - } - if ((state & DRAW_OFFSET) != 0) { - data.drawXOffset = data.drawYOffset = 0; - CGSize size = new CGSize(); - size.width = size.height = 1; - if (data.transform != null) { - OS.CGSizeApplyAffineTransform(size, data.transform, size); - } - float scaling = size.width; - if (scaling < 0) scaling = -scaling; - float strokeWidth = data.lineWidth * scaling; - if (strokeWidth == 0 || ((int)strokeWidth % 2) == 1) { - data.drawXOffset = 0.5f / scaling; - } - scaling = size.height; - if (scaling < 0) scaling = -scaling; - strokeWidth = data.lineWidth * scaling; - if (strokeWidth == 0 || ((int)strokeWidth % 2) == 1) { - data.drawYOffset = 0.5f / scaling; - } - } -} - -int convertRgn(int rgn, float[] transform) { - int newRgn = OS.NewRgn(); - Callback callback = new Callback(this, "convertRgn", 4); - int proc = callback.getAddress(); - if (proc == 0) SWT.error(SWT.ERROR_NO_MORE_CALLBACKS); - float[] clippingTranform = data.clippingTransform; - data.clippingTransform = transform; - OS.QDRegionToRects(rgn, OS.kQDParseRegionFromTopLeft, proc, newRgn); - data.clippingTransform = clippingTranform; - callback.dispose(); - return newRgn; -} - -int convertRgn(int message, int rgn, int r, int newRgn) { - if (message == OS.kQDRegionToRectsMsgParse) { - Rect rect = new Rect(); - OS.memmove(rect, r, Rect.sizeof); - CGPoint point = new CGPoint(); - int polyRgn = OS.NewRgn(); - OS.OpenRgn(); - point.x = rect.left; - point.y = rect.top; - float[] transform = data.clippingTransform; - OS.CGPointApplyAffineTransform(point, transform, point); - short startX, startY; - OS.MoveTo(startX = (short)point.x, startY = (short)point.y); - point.x = rect.right; - point.y = rect.top; - OS.CGPointApplyAffineTransform(point, transform, point); - OS.LineTo((short)Math.round(point.x), (short)point.y); - point.x = rect.right; - point.y = rect.bottom; - OS.CGPointApplyAffineTransform(point, transform, point); - OS.LineTo((short)Math.round(point.x), (short)Math.round(point.y)); - point.x = rect.left; - point.y = rect.bottom; - OS.CGPointApplyAffineTransform(point, transform, point); - OS.LineTo((short)point.x, (short)Math.round(point.y)); - OS.LineTo(startX, startY); - OS.CloseRgn(polyRgn); - OS.UnionRgn(newRgn, polyRgn, newRgn); - OS.DisposeRgn(polyRgn); - } - return 0; -} - -/** - * Copies a rectangular area of the receiver at the specified - * position into the image, which must be of type <code>SWT.BITMAP</code>. - * - * @param image the image to copy into - * @param x the x coordinate in the receiver of the area to be copied - * @param y the y coordinate in the receiver of the area to be copied - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the image is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the image is not a bitmap or has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void copyArea(Image image, int x, int y) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (image.type != SWT.BITMAP || image.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - if (data.image != null) { - copyArea(image, x, y, data.image.handle); - } else if (data.control != 0) { - int imageHandle = image.handle; - int width = OS.CGImageGetWidth(imageHandle); - int height = OS.CGImageGetHeight(imageHandle); - int window = OS.GetControlOwner(data.control); - Rect srcRect = new Rect (); - CGPoint pt = new CGPoint (); - int[] contentView = new int[1]; - OS.HIViewFindByID(OS.HIViewGetRoot(window), OS.kHIViewWindowContentID(), contentView); - OS.HIViewConvertPoint (pt, data.control, contentView[0]); - x += (int) pt.x; - y += (int) pt.y; - Rect inset = data.insetRect; - x -= inset.left; - y -= inset.top; - srcRect.left = (short)x; - srcRect.top = (short)y; - srcRect.right = (short)(x + width); - srcRect.bottom = (short)(y + height); - Rect destRect = new Rect(); - destRect.right = (short)width; - destRect.bottom = (short)height; - int bpl = width * 4; - int[] gWorld = new int[1]; - int port = OS.GetWindowPort(window); - OS.NewGWorldFromPtr(gWorld, OS.k32ARGBPixelFormat, destRect, 0, 0, 0, image.data, bpl); - OS.CopyBits(OS.GetPortBitMapForCopyBits(port), OS.GetPortBitMapForCopyBits(gWorld[0]), srcRect, destRect, (short)OS.srcCopy, 0); - OS.DisposeGWorld(gWorld [0]); - } else if (data.window != 0) { - int imageHandle = image.handle; - CGRect rect = new CGRect(); - rect.x = x; - rect.y = y; - rect.width = OS.CGImageGetWidth(imageHandle); - rect.height = OS.CGImageGetHeight(imageHandle); - int[] displays = new int[16]; - int[] count = new int[1]; - if (OS.CGGetDisplaysWithRect(rect, displays.length, displays, count) != 0) return; - for (int i = 0; i < count[0]; i++) { - int display = displays[i]; - OS.CGDisplayBounds(display, rect); - int address = OS.CGDisplayBaseAddress(display); - if (address != 0) { - int width = OS.CGDisplayPixelsWide(display); - int height = OS.CGDisplayPixelsHigh(display); - int bpr = OS.CGDisplayBytesPerRow(display); - int bpp = OS.CGDisplayBitsPerPixel(display); - int bps = OS.CGDisplayBitsPerSample(display); - int bitmapInfo = OS.kCGImageAlphaNoneSkipFirst; - switch (bpp) { - case 16: bitmapInfo |= OS.kCGBitmapByteOrder16Host; break; - case 32: bitmapInfo |= OS.kCGBitmapByteOrder32Host; break; - } - int srcImage = 0; - if (OS.__BIG_ENDIAN__() && OS.VERSION >= 0x1040) { - int context = OS.CGBitmapContextCreate(address, width, height, bps, bpr, data.device.colorspace, bitmapInfo); - srcImage = OS.CGBitmapContextCreateImage(context); - OS.CGContextRelease(context); - } else { - int provider = OS.CGDataProviderCreateWithData(0, address, bpr * height, 0); - srcImage = OS.CGImageCreate(width, height, bps, bpp, bpr, data.device.colorspace, bitmapInfo, provider, null, true, 0); - OS.CGDataProviderRelease(provider); - } - copyArea(image, x - (int)rect.x, y - (int)rect.y, srcImage); - if (srcImage != 0) OS.CGImageRelease(srcImage); - } - } - } -} - -void copyArea (Image image, int x, int y, int srcImage) { - if (srcImage == 0) return; - int imageHandle = image.handle; - int bpc = OS.CGImageGetBitsPerComponent(imageHandle); - int width = OS.CGImageGetWidth(imageHandle); - int height = OS.CGImageGetHeight(imageHandle); - int bpr = OS.CGImageGetBytesPerRow(imageHandle); - int alphaInfo = OS.CGImageGetAlphaInfo(imageHandle); - int context = OS.CGBitmapContextCreate(image.data, width, height, bpc, bpr, data.device.colorspace, alphaInfo); - if (context != 0) { - CGRect rect = new CGRect(); - rect.x = -x; - rect.y = y; - rect.width = OS.CGImageGetWidth(srcImage); - rect.height = OS.CGImageGetHeight(srcImage); - OS.CGContextTranslateCTM(context, 0, -(rect.height - height)); - OS.CGContextDrawImage(context, rect, srcImage); - OS.CGContextRelease(context); - } -} - -/** - * Copies a rectangular area of the receiver at the source - * position onto the receiver at the destination position. - * - * @param srcX the x coordinate in the receiver of the area to be copied - * @param srcY the y coordinate in the receiver of the area to be copied - * @param width the width of the area to copy - * @param height the height of the area to copy - * @param destX the x coordinate in the receiver of the area to copy to - * @param destY the y coordinate in the receiver of the area to copy to - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void copyArea(int srcX, int srcY, int width, int height, int destX, int destY) { - copyArea(srcX, srcY, width, height, destX, destY, true); -} -/** - * Copies a rectangular area of the receiver at the source - * position onto the receiver at the destination position. - * - * @param srcX the x coordinate in the receiver of the area to be copied - * @param srcY the y coordinate in the receiver of the area to be copied - * @param width the width of the area to copy - * @param height the height of the area to copy - * @param destX the x coordinate in the receiver of the area to copy to - * @param destY the y coordinate in the receiver of the area to copy to - * @param paint if <code>true</code> paint events will be generated for old and obscured areas - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.1 - */ -public void copyArea(int srcX, int srcY, int width, int height, int destX, int destY, boolean paint) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (data.updateClip) setCGClipping(); - if (width <= 0 || height <= 0) return; - int deltaX = destX - srcX, deltaY = destY - srcY; - if (deltaX == 0 && deltaY == 0) return; - if (data.image != null) { - OS.CGContextSaveGState(handle); - OS.CGContextScaleCTM(handle, 1, -1); - OS.CGContextTranslateCTM(handle, 0, -(height + 2 * destY)); - CGRect rect = new CGRect(); - rect.x = destX; - rect.y = destY; - rect.width = width; - rect.height = height; - int h = OS.CGImageGetHeight(data.image.handle); - int bpr = OS.CGImageGetBytesPerRow(data.image.handle); - int provider = OS.CGDataProviderCreateWithData(0, data.image.data, bpr * h, 0); - if (provider != 0) { - int colorspace = device.colorspace; - int img = OS.CGImageCreate(width, height, 8, 32, bpr, colorspace, OS.kCGImageAlphaNoneSkipFirst, provider, null, true, 0); - OS.CGDataProviderRelease(provider); - OS.CGContextDrawImage(handle, rect, img); - OS.CGImageRelease(img); - } - OS.CGContextRestoreGState(handle); - return; - } - if (data.control != 0) { - int port = data.port; - int window = OS.GetControlOwner(data.control); - if (port == 0) port = OS.GetWindowPort(window); - - /* Calculate src and dest rectangles/regions */ - Rect rect = new Rect(); - OS.GetControlBounds(data.control, rect); - int convertX = 0, convertY = 0; - CGPoint pt = new CGPoint (); - int[] contentView = new int[1]; - OS.HIViewFindByID(OS.HIViewGetRoot(window), OS.kHIViewWindowContentID(), contentView); - OS.HIViewConvertPoint(pt, OS.HIViewGetSuperview(data.control), contentView[0]); - convertX = rect.left + (int) pt.x; - convertY = rect.top + (int) pt.y; - rect.left += (int) pt.x; - rect.top += (int) pt.y; - rect.right += (int) pt.x; - rect.bottom += (int) pt.y; - Rect srcRect = new Rect(); - int left = rect.left + srcX; - int top = rect.top + srcY; - OS.SetRect(srcRect, (short)left, (short)top, (short)(left + width), (short)(top + height)); - int srcRgn = OS.NewRgn(); - OS.RectRgn(srcRgn, srcRect); - OS.SectRect(rect, srcRect, srcRect); - Rect destRect = new Rect (); - OS.SetRect(destRect, srcRect.left, srcRect.top, srcRect.right, srcRect.bottom); - OS.OffsetRect(destRect, (short)deltaX, (short)deltaY); - int destRgn = OS.NewRgn(); - OS.RectRgn(destRgn, destRect); - - /* Copy bits with appropriated clipping region */ - if (!OS.EmptyRect(srcRect)) { - if (data.visibleRgn == 0 || OS.RectInRgn(srcRect, data.visibleRgn)) { - int clipRgn = data.visibleRgn; - if (data.clipRgn != 0) { - clipRgn = OS.NewRgn(); - OS.SectRgn(data.clipRgn, data.visibleRgn, clipRgn); - } - - /* - * Feature in the Macintosh. ScrollRect() only copies bits - * that are inside the specified rectangle. This means that - * it is not possible to copy non overlaping bits without - * copying the bits in between the source and destination - * rectangles. The fix is to check if the source and - * destination rectangles are disjoint and use CopyBits() - * instead. - */ - if (!OS.EmptyRgn(clipRgn)) { - boolean disjoint = (destX + width < srcX) || (srcX + width < destX) || (destY + height < srcY) || (srcY + height < destY); - if (!disjoint && (deltaX == 0 || deltaY == 0)) { - int[] currentPort = new int[1]; - OS.GetPort(currentPort); - OS.SetPort(port); - int oldClip = OS.NewRgn(); - OS.GetClip(oldClip); - OS.SetClip(clipRgn); - OS.UnionRect(srcRect, destRect, rect); - OS.ScrollRect(rect, (short)deltaX, (short)deltaY, 0); - OS.SetClip(oldClip); - OS.DisposeRgn(oldClip); - OS.SetPort(currentPort[0]); - } else { - int portBitMap = OS.GetPortBitMapForCopyBits (port); - OS.CopyBits(portBitMap, portBitMap, srcRect, destRect, (short)OS.srcCopy, clipRgn); - OS.QDFlushPortBuffer(port, destRgn); - } - } - - if (clipRgn != data.visibleRgn) OS.DisposeRgn(clipRgn); - } - } - - /* Invalidate src and obscured areas */ - if (paint) { - int invalRgn = OS.NewRgn(); - OS.DiffRgn(srcRgn, data.visibleRgn, invalRgn); - OS.OffsetRgn(invalRgn, (short)deltaX, (short)deltaY); - OS.DiffRgn(srcRgn, destRgn, srcRgn); - OS.UnionRgn(srcRgn, invalRgn, invalRgn); - OS.SectRgn(data.visibleRgn, invalRgn, invalRgn); - OS.OffsetRgn(invalRgn, (short)-convertX, (short)-convertY); - OS.HIViewSetNeedsDisplayInRegion(data.control, invalRgn, true); - OS.DisposeRgn(invalRgn); - } - - /* Dispose src and dest regions */ - OS.DisposeRgn(destRgn); - OS.DisposeRgn(srcRgn); - } -} - -void createLayout () { - int[] buffer = new int[1]; - OS.ATSUCreateTextLayout(buffer); - if (buffer[0] == 0) SWT.error(SWT.ERROR_NO_HANDLES); - data.layout = buffer[0]; - int ptr1 = OS.NewPtr(4); - buffer[0] = handle; - OS.memmove(ptr1, buffer, 4); - int ptr2 = OS.NewPtr(4); - buffer[0] = OS.kATSLineUseDeviceMetrics; - OS.memmove(ptr2, buffer, 4); - int lineDir = OS.kATSULeftToRightBaseDirection; - if ((data.style & SWT.RIGHT_TO_LEFT) != 0) lineDir = OS.kATSURightToLeftBaseDirection; - int ptr3 = OS.NewPtr(1); - OS.memmove(ptr3, new byte[] {(byte)lineDir}, 1); - int[] tags = new int[]{OS.kATSUCGContextTag, OS.kATSULineLayoutOptionsTag, OS.kATSULineDirectionTag}; - int[] sizes = new int[]{4, 4, 1}; - int[] values = new int[]{ptr1, ptr2, ptr3}; - OS.ATSUSetLayoutControls(data.layout, tags.length, tags, sizes, values); - OS.DisposePtr(ptr1); - OS.DisposePtr(ptr2); - OS.DisposePtr(ptr3); -} - -void createTabs () { - ATSUTab tabs = new ATSUTab(); - int tabWidth = getCharWidth(' ') * 8; - int ptr = OS.NewPtr(ATSUTab.sizeof * TAB_COUNT); - for (int i=0, offset=ptr; i<TAB_COUNT; i++, offset += ATSUTab.sizeof) { - tabs.tabPosition += OS.Long2Fix(tabWidth); - OS.memmove(offset, tabs, ATSUTab.sizeof); - } - data.tabs = ptr; -} - -void destroy() { - /* Free resources */ - int clipRgn = data.clipRgn; - if (clipRgn != 0) OS.DisposeRgn(clipRgn); - Image image = data.image; - if (image != null) { - image.memGC = null; - image.createAlpha(); - } - int layout = data.layout; - if (layout != 0) OS.ATSUDisposeTextLayout(layout); - int atsuiStyle = data.atsuiStyle; - if (atsuiStyle != 0) OS.ATSUDisposeStyle(atsuiStyle); - int stringPtr = data.stringPtr; - if (stringPtr != 0) OS.DisposePtr(stringPtr); - int tabs = data.tabs; - if (tabs != 0) OS.DisposePtr(tabs); - int forePattern = data.forePattern; - if (forePattern != 0) OS.CGPatternRelease(forePattern); - int backPattern = data.backPattern; - if (backPattern != 0) OS.CGPatternRelease(backPattern); - - /* Dispose the GC */ - if (drawable != null) drawable.internal_dispose_GC(handle, data); - - data.clipRgn = data.atsuiStyle = data.stringPtr = data.layout = data.tabs = data.forePattern = data.backPattern = 0; - drawable = null; - data.image = null; - data.string = null; - data = null; - handle = 0; -} - -/** - * Draws the outline of a circular or elliptical arc - * within the specified rectangular area. - * <p> - * The resulting arc begins at <code>startAngle</code> and extends - * for <code>arcAngle</code> degrees, using the current color. - * Angles are interpreted such that 0 degrees is at the 3 o'clock - * position. A positive value indicates a counter-clockwise rotation - * while a negative value indicates a clockwise rotation. - * </p><p> - * The center of the arc is the center of the rectangle whose origin - * is (<code>x</code>, <code>y</code>) and whose size is specified by the - * <code>width</code> and <code>height</code> arguments. - * </p><p> - * The resulting arc covers an area <code>width + 1</code> pixels wide - * by <code>height + 1</code> pixels tall. - * </p> - * - * @param x the x coordinate of the upper-left corner of the arc to be drawn - * @param y the y coordinate of the upper-left corner of the arc to be drawn - * @param width the width of the arc to be drawn - * @param height the height of the arc to be drawn - * @param startAngle the beginning angle - * @param arcAngle the angular extent of the arc, relative to the start angle - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - checkGC(DRAW); - if (data.updateClip) setCGClipping(); - if (width < 0) { - x = x + width; - width = -width; - } - if (height < 0) { - y = y + height; - height = -height; - } - if (width == 0 || height == 0 || arcAngle == 0) return; - OS.CGContextBeginPath(handle); - OS.CGContextSaveGState(handle); - float xOffset = data.drawXOffset, yOffset = data.drawYOffset; - OS.CGContextTranslateCTM(handle, x + xOffset + width / 2f, y + yOffset + height / 2f); - OS.CGContextScaleCTM(handle, width / 2f, height / 2f); - if (arcAngle < 0) { - OS.CGContextAddArc(handle, 0, 0, 1, -(startAngle + arcAngle) * (float)Compatibility.PI / 180, -startAngle * (float)Compatibility.PI / 180, true); - } else { - OS.CGContextAddArc(handle, 0, 0, 1, -startAngle * (float)Compatibility.PI / 180, -(startAngle + arcAngle) * (float)Compatibility.PI / 180, true); - } - OS.CGContextRestoreGState(handle); - OS.CGContextStrokePath(handle); - flush(); -} - -/** - * Draws a rectangle, based on the specified arguments, which has - * the appearance of the platform's <em>focus rectangle</em> if the - * platform supports such a notion, and otherwise draws a simple - * rectangle in the receiver's foreground color. - * - * @param x the x coordinate of the rectangle - * @param y the y coordinate of the rectangle - * @param width the width of the rectangle - * @param height the height of the rectangle - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #drawRectangle(int, int, int, int) - */ -public void drawFocus(int x, int y, int width, int height) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (data.updateClip) setCGClipping(); - 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(); -} - -/** - * Draws the given image in the receiver at the specified - * coordinates. - * - * @param image the image to draw - * @param x the x coordinate of where to draw - * @param y the y coordinate of where to draw - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the image is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li> - * <li>ERROR_INVALID_ARGUMENT - if the given coordinates are outside the bounds of the image</li> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES - if no handles are available to perform the operation</li> - * </ul> - */ -public void drawImage(Image image, int x, int y) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (image.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - drawImage(image, 0, 0, -1, -1, x, y, -1, -1, true); -} - -/** - * Copies a rectangular area from the source image into a (potentially - * different sized) rectangular area in the receiver. If the source - * and destination areas are of differing sizes, then the source - * area will be stretched or shrunk to fit the destination area - * as it is copied. The copy fails if any part of the source rectangle - * lies outside the bounds of the source image, or if any of the width - * or height arguments are negative. - * - * @param image the source image - * @param srcX the x coordinate in the source image to copy from - * @param srcY the y coordinate in the source image to copy from - * @param srcWidth the width in pixels to copy from the source - * @param srcHeight the height in pixels to copy from the source - * @param destX the x coordinate in the destination to copy to - * @param destY the y coordinate in the destination to copy to - * @param destWidth the width in pixels of the destination rectangle - * @param destHeight the height in pixels of the destination rectangle - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the image is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li> - * <li>ERROR_INVALID_ARGUMENT - if any of the width or height arguments are negative. - * <li>ERROR_INVALID_ARGUMENT - if the source rectangle is not contained within the bounds of the source image</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES - if no handles are available to perform the operation</li> - * </ul> - */ -public void drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (srcWidth == 0 || srcHeight == 0 || destWidth == 0 || destHeight == 0) return; - if (srcX < 0 || srcY < 0 || srcWidth < 0 || srcHeight < 0 || destWidth < 0 || destHeight < 0) { - SWT.error (SWT.ERROR_INVALID_ARGUMENT); - } - if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (image.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - drawImage(image, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, false); -} - -void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple) { - if (data.updateClip) setCGClipping(); - int imageHandle = srcImage.handle; - int imgWidth = OS.CGImageGetWidth(imageHandle); - int imgHeight = OS.CGImageGetHeight(imageHandle); - if (simple) { - srcWidth = destWidth = imgWidth; - srcHeight = destHeight = imgHeight; - } else { - simple = srcX == 0 && srcY == 0 && - srcWidth == destWidth && destWidth == imgWidth && - srcHeight == destHeight && destHeight == imgHeight; - if (srcX + srcWidth > imgWidth || srcY + srcHeight > imgHeight) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - } - if (srcImage.memGC != null) srcImage.createAlpha(); - OS.CGContextSaveGState(handle); - OS.CGContextScaleCTM(handle, 1, -1); - OS.CGContextTranslateCTM(handle, 0, -(destHeight + 2 * destY)); - CGRect rect = new CGRect(); - rect.x = destX; - rect.y = destY; - rect.width = destWidth; - rect.height = destHeight; - if (simple) { - OS.CGContextDrawImage(handle, rect, imageHandle); - } else { - int bpc = OS.CGImageGetBitsPerComponent(imageHandle); - int bpp = OS.CGImageGetBitsPerPixel(imageHandle); - int bpr = OS.CGImageGetBytesPerRow(imageHandle); - int colorspace = OS.CGImageGetColorSpace(imageHandle); - int alphaInfo = OS.CGImageGetAlphaInfo(imageHandle); - int data = srcImage.data + (srcY * bpr) + srcX * 4; - int provider = OS.CGDataProviderCreateWithData(0, data, srcHeight * bpr, 0); - if (provider != 0) { - int subImage = OS.CGImageCreate(srcWidth, srcHeight, bpc, bpp, bpr, colorspace, alphaInfo, provider, null, true, 0); - OS.CGDataProviderRelease(provider); - if (subImage != 0) { - OS.CGContextDrawImage(handle, rect, subImage); - OS.CGImageRelease(subImage); - } - } - } - OS.CGContextRestoreGState(handle); - flush(); -} - -/** - * Draws a line, using the foreground color, between the points - * (<code>x1</code>, <code>y1</code>) and (<code>x2</code>, <code>y2</code>). - * - * @param x1 the first point's x coordinate - * @param y1 the first point's y coordinate - * @param x2 the second point's x coordinate - * @param y2 the second point's y coordinate - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void drawLine(int x1, int y1, int x2, int y2) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - checkGC(DRAW); - if (data.updateClip) setCGClipping(); - if (x1 == x2 && y1 == y2 && data.lineWidth <= 1) { - drawPoint(x1, y1); - return; - } - OS.CGContextBeginPath(handle); - float xOffset = data.drawXOffset, yOffset = data.drawYOffset; - OS.CGContextMoveToPoint(handle, x1 + xOffset, y1 + yOffset); - OS.CGContextAddLineToPoint(handle, x2 + xOffset, y2 + yOffset); - OS.CGContextStrokePath(handle); - flush(); -} - -/** - * Draws the outline of an oval, using the foreground color, - * within the specified rectangular area. - * <p> - * The result is a circle or ellipse that fits within the - * rectangle specified by the <code>x</code>, <code>y</code>, - * <code>width</code>, and <code>height</code> arguments. - * </p><p> - * The oval covers an area that is <code>width + 1</code> - * pixels wide and <code>height + 1</code> pixels tall. - * </p> - * - * @param x the x coordinate of the upper left corner of the oval to be drawn - * @param y the y coordinate of the upper left corner of the oval to be drawn - * @param width the width of the oval to be drawn - * @param height the height of the oval to be drawn - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void drawOval(int x, int y, int width, int height) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - checkGC(DRAW); - if (data.updateClip) setCGClipping(); - if (width < 0) { - x = x + width; - width = -width; - } - if (height < 0) { - y = y + height; - height = -height; - } - OS.CGContextBeginPath(handle); - OS.CGContextSaveGState(handle); - float xOffset = data.drawXOffset, yOffset = data.drawYOffset; - OS.CGContextTranslateCTM(handle, x + xOffset + width / 2f, y + yOffset + height / 2f); - OS.CGContextScaleCTM(handle, width / 2f, height / 2f); - OS.CGContextMoveToPoint(handle, 1, 0); - OS.CGContextAddArc(handle, 0, 0, 1, 0, (float)(2 *Compatibility.PI), true); - OS.CGContextRestoreGState(handle); - OS.CGContextStrokePath(handle); - flush(); -} - -/** - * Draws the path described by the parameter. - * <p> - * This operation requires the operating system's advanced - * graphics subsystem which may not be available on some - * platforms. - * </p> - * - * @param path the path to draw - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the parameter is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the parameter has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> - * </ul> - * - * @see Path - * - * @since 3.1 - */ -public void drawPath(Path path) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (path == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (path.handle == 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - checkGC(DRAW); - if (data.updateClip) setCGClipping(); - OS.CGContextBeginPath(handle); - OS.CGContextSaveGState(handle); - float xOffset = data.drawXOffset, yOffset = data.drawYOffset; - OS.CGContextTranslateCTM(handle, xOffset, yOffset); - OS.CGContextAddPath(handle, path.handle); - OS.CGContextRestoreGState(handle); - OS.CGContextStrokePath(handle); - flush(); -} - -/** - * Draws a pixel, using the foreground color, at the specified - * point (<code>x</code>, <code>y</code>). - * <p> - * Note that the receiver's line attributes do not affect this - * operation. - * </p> - * - * @param x the point's x coordinate - * @param y the point's y coordinate - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.0 - */ -public void drawPoint(int x, int y) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - checkGC(FOREGROUND_FILL); - if (data.updateClip) setCGClipping(); - CGRect rect = new CGRect(); - rect.x = x; - rect.y = y; - rect.width = 1; - rect.height = 1; - OS.CGContextFillRect(handle, rect); - flush(); -} - -/** - * Draws the closed polygon which is defined by the specified array - * of integer coordinates, using the receiver's foreground color. The array - * contains alternating x and y values which are considered to represent - * points which are the vertices of the polygon. Lines are drawn between - * each consecutive pair, and between the first pair and last pair in the - * array. - * - * @param pointArray an array of alternating x and y values which are the vertices of the polygon - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT if pointArray is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void drawPolygon(int[] pointArray) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (pointArray == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - checkGC(DRAW); - if (data.updateClip) setCGClipping(); - float xOffset = data.drawXOffset, yOffset = data.drawYOffset; - float[] points = new float[(pointArray.length / 2) * 2]; - for (int i=0; i<points.length; i+=2) { - points[i] = pointArray[i] + xOffset; - points[i+1] = pointArray[i+1] + yOffset; - } - OS.CGContextBeginPath(handle); - OS.CGContextAddLines(handle, points, points.length / 2); - OS.CGContextClosePath(handle); - OS.CGContextStrokePath(handle); - flush(); -} - -/** - * Draws the polyline which is defined by the specified array - * of integer coordinates, using the receiver's foreground color. The array - * contains alternating x and y values which are considered to represent - * points which are the corners of the polyline. Lines are drawn between - * each consecutive pair, but not between the first pair and last pair in - * the array. - * - * @param pointArray an array of alternating x and y values which are the corners of the polyline - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the point array is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void drawPolyline(int[] pointArray) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (pointArray == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - checkGC(DRAW); - if (data.updateClip) setCGClipping(); - float xOffset = data.drawXOffset, yOffset = data.drawYOffset; - float[] points = new float[(pointArray.length / 2) * 2]; - for (int i=0; i<points.length; i+=2) { - points[i] = pointArray[i] + xOffset; - points[i+1] = pointArray[i+1] + yOffset; - } - OS.CGContextBeginPath(handle); - OS.CGContextAddLines(handle, points, points.length / 2); - OS.CGContextStrokePath(handle); - flush(); -} - -/** - * Draws the outline of the rectangle specified by the arguments, - * using the receiver's foreground color. The left and right edges - * of the rectangle are at <code>x</code> and <code>x + width</code>. - * The top and bottom edges are at <code>y</code> and <code>y + height</code>. - * - * @param x the x coordinate of the rectangle to be drawn - * @param y the y coordinate of the rectangle to be drawn - * @param width the width of the rectangle to be drawn - * @param height the height of the rectangle to be drawn - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void drawRectangle(int x, int y, int width, int height) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - checkGC(DRAW); - if (data.updateClip) setCGClipping(); - if (width < 0) { - x = x + width; - width = -width; - } - if (height < 0) { - y = y + height; - height = -height; - } - CGRect rect = new CGRect(); - float xOffset = data.drawXOffset, yOffset = data.drawYOffset; - rect.x = x + xOffset; - rect.y = y + yOffset; - rect.width = width; - rect.height = height; - OS.CGContextStrokeRect(handle, rect); - flush(); -} - -/** - * Draws the outline of the specified rectangle, using the receiver's - * foreground color. The left and right edges of the rectangle are at - * <code>rect.x</code> and <code>rect.x + rect.width</code>. The top - * and bottom edges are at <code>rect.y</code> and - * <code>rect.y + rect.height</code>. - * - * @param rect the rectangle to draw - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void drawRectangle(Rectangle rect) { - if (rect == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - drawRectangle (rect.x, rect.y, rect.width, rect.height); -} - -/** - * Draws the outline of the round-cornered rectangle specified by - * the arguments, using the receiver's foreground color. The left and - * right edges of the rectangle are at <code>x</code> and <code>x + width</code>. - * The top and bottom edges are at <code>y</code> and <code>y + height</code>. - * The <em>roundness</em> of the corners is specified by the - * <code>arcWidth</code> and <code>arcHeight</code> arguments, which - * are respectively the width and height of the ellipse used to draw - * the corners. - * - * @param x the x coordinate of the rectangle to be drawn - * @param y the y coordinate of the rectangle to be drawn - * @param width the width of the rectangle to be drawn - * @param height the height of the rectangle to be drawn - * @param arcWidth the width of the arc - * @param arcHeight the height of the arc - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void drawRoundRectangle(int x, int y, int width, int height, int arcWidth, int arcHeight) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - checkGC(DRAW); - if (data.updateClip) setCGClipping(); - if (arcWidth == 0 || arcHeight == 0) { - drawRectangle(x, y, width, height); - return; - } - int nx = x; - int ny = y; - int nw = width; - int nh = height; - int naw = arcWidth; - int nah = arcHeight; - if (nw < 0) { - nw = 0 - nw; - nx = nx - nw; - } - if (nh < 0) { - nh = 0 - nh; - ny = ny - nh; - } - if (naw < 0) naw = 0 - naw; - if (nah < 0) nah = 0 - nah; - if (naw > nw) naw = nw; - if (nah > nh) nah = nh; - float naw2 = naw / 2f; - float nah2 = nah / 2f; - float fw = nw / naw2; - float fh = nh / nah2; - OS.CGContextBeginPath(handle); - OS.CGContextSaveGState(handle); - float xOffset = data.drawXOffset, yOffset = data.drawYOffset; - OS.CGContextTranslateCTM(handle, nx + xOffset, ny + yOffset); - OS.CGContextScaleCTM(handle, naw2, nah2); - OS.CGContextMoveToPoint(handle, fw - 1, 0); - OS.CGContextAddArcToPoint(handle, 0, 0, 0, 1, 1); - OS.CGContextAddArcToPoint(handle, 0, fh, 1, fh, 1); - OS.CGContextAddArcToPoint(handle, fw, fh, fw, fh - 1, 1); - OS.CGContextAddArcToPoint(handle, fw, 0, fw - 1, 0, 1); - OS.CGContextClosePath(handle); - OS.CGContextRestoreGState(handle); - OS.CGContextStrokePath(handle); - flush(); -} - -/** - * Draws the given string, using the receiver's current font and - * foreground color. No tab expansion or carriage return processing - * will be performed. The background of the rectangular area where - * the string is being drawn will be filled with the receiver's - * background color. - * - * @param string the string to be drawn - * @param x the x coordinate of the top left corner of the rectangular area where the string is to be drawn - * @param y the y coordinate of the top left corner of the rectangular area where the string is to be drawn - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the string is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void drawString (String string, int x, int y) { - drawString(string, x, y, false); -} - -/** - * Draws the given string, using the receiver's current font and - * foreground color. No tab expansion or carriage return processing - * will be performed. If <code>isTransparent</code> is <code>true</code>, - * then the background of the rectangular area where the string is being - * drawn will not be modified, otherwise it will be filled with the - * receiver's background color. - * - * @param string the string to be drawn - * @param x the x coordinate of the top left corner of the rectangular area where the string is to be drawn - * @param y the y coordinate of the top left corner of the rectangular area where the string is to be drawn - * @param isTransparent if <code>true</code> the background will be transparent, otherwise it will be opaque - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the string is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void drawString(String string, int x, int y, boolean isTransparent) { - drawText(string, x, y, isTransparent ? SWT.DRAW_TRANSPARENT : 0); -} - -/** - * Draws the given string, using the receiver's current font and - * foreground color. Tab expansion and carriage return processing - * are performed. The background of the rectangular area where - * the text is being drawn will be filled with the receiver's - * background color. - * - * @param string the string to be drawn - * @param x the x coordinate of the top left corner of the rectangular area where the text is to be drawn - * @param y the y coordinate of the top left corner of the rectangular area where the text is to be drawn - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the string is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void drawText(String string, int x, int y) { - drawText(string, x, y, SWT.DRAW_DELIMITER | SWT.DRAW_TAB); -} - -/** - * Draws the given string, using the receiver's current font and - * foreground color. Tab expansion and carriage return processing - * are performed. If <code>isTransparent</code> is <code>true</code>, - * then the background of the rectangular area where the text is being - * drawn will not be modified, otherwise it will be filled with the - * receiver's background color. - * - * @param string the string to be drawn - * @param x the x coordinate of the top left corner of the rectangular area where the text is to be drawn - * @param y the y coordinate of the top left corner of the rectangular area where the text is to be drawn - * @param isTransparent if <code>true</code> the background will be transparent, otherwise it will be opaque - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the string is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void drawText(String string, int x, int y, boolean isTransparent) { - int flags = SWT.DRAW_DELIMITER | SWT.DRAW_TAB; - if (isTransparent) flags |= SWT.DRAW_TRANSPARENT; - drawText(string, x, y, flags); -} - -/** - * Draws the given string, using the receiver's current font and - * foreground color. Tab expansion, line delimiter and mnemonic - * processing are performed according to the specified flags. If - * <code>flags</code> includes <code>DRAW_TRANSPARENT</code>, - * then the background of the rectangular area where the text is being - * drawn will not be modified, otherwise it will be filled with the - * receiver's background color. - * <p> - * The parameter <code>flags</code> may be a combination of: - * <dl> - * <dt><b>DRAW_DELIMITER</b></dt> - * <dd>draw multiple lines</dd> - * <dt><b>DRAW_TAB</b></dt> - * <dd>expand tabs</dd> - * <dt><b>DRAW_MNEMONIC</b></dt> - * <dd>underline the mnemonic character</dd> - * <dt><b>DRAW_TRANSPARENT</b></dt> - * <dd>transparent background</dd> - * </dl> - * </p> - * - * @param string the string to be drawn - * @param x the x coordinate of the top left corner of the rectangular area where the text is to be drawn - * @param y the y coordinate of the top left corner of the rectangular area where the text is to be drawn - * @param flags the flags specifying how to process the text - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the string is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void drawText (String string, int x, int y, int flags) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (string == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - checkGC(FONT | FOREGROUND_FILL); - if (data.updateClip) setCGClipping(); - int length = string.length(); - if (length == 0) return; - OS.CGContextSaveGState(handle); - OS.CGContextScaleCTM(handle, 1, -1); - boolean mode = true; - switch (data.textAntialias) { - case SWT.DEFAULT: - /* Printer is off by default */ - if (data.window == 0 && data.control == 0 && data.image == null) mode = false; - break; - case SWT.OFF: mode = false; break; - } - OS.CGContextSetShouldAntialias(handle, mode); - length = setString(string, flags); - if ((flags & SWT.DRAW_DELIMITER) != 0) { - int layout = data.layout; - int[] breakCount = new int[1]; - OS.ATSUGetSoftLineBreaks(layout, 0, length, 0, null, breakCount); - int[] breaks = new int[breakCount[0] + 1]; - OS.ATSUGetSoftLineBreaks(layout, 0, length, breakCount[0], breaks, breakCount); - breaks[breakCount[0]] = length; - for (int i=0, start=0; i<breaks.length; i++) { - int lineBreak = breaks[i]; - drawText(x, y, start, lineBreak - start, flags); - y += data.fontAscent + data.fontDescent; - start = lineBreak; - } - } else { - drawText(x, y, 0, length, flags); - } - OS.CGContextRestoreGState(handle); - flush(); -} - -void drawText(int x, int y, int start, int length, int flags) { - int layout = data.layout; - if ((flags & SWT.DRAW_TRANSPARENT) == 0) { - ATSTrapezoid trapezoid = new ATSTrapezoid(); - OS.ATSUGetGlyphBounds(layout, 0, 0, start, length, (short)OS.kATSUseDeviceOrigins, 1, trapezoid, null); - int width = OS.Fix2Long(trapezoid.lowerRight_x) - OS.Fix2Long(trapezoid.lowerLeft_x); - int height = OS.Fix2Long(trapezoid.lowerRight_y) - OS.Fix2Long(trapezoid.upperRight_y); - CGRect rect = new CGRect(); - rect.x = x; - rect.y = -(y + height); - rect.width = width; - rect.height = height; - OS.CGContextSaveGState(handle); - Pattern pattern = data.backgroundPattern; - if (pattern != null) { - int colorspace = OS.CGColorSpaceCreatePattern(data.device.colorspace); - OS.CGContextSetFillColorSpace(handle, colorspace); - OS.CGColorSpaceRelease(colorspace); - if (data.backPattern == 0) data.backPattern = pattern.createPattern(handle); - OS.CGContextSetFillPattern(handle, data.backPattern, data.background); - } else { - OS.CGContextSetFillColorSpace(handle, data.device.colorspace); - OS.CGContextSetFillColor(handle, data.background); - } - OS.CGContextFillRect(handle, rect); - OS.CGContextRestoreGState(handle); - } - OS.ATSUDrawText(layout, start, length, OS.Long2Fix(x), OS.Long2Fix(-(y + data.fontAscent))); -} - -/** - * Compares the argument to the receiver, and returns true - * if they represent the <em>same</em> object using a class - * specific comparison. - * - * @param object the object to compare with this object - * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise - * - * @see #hashCode - */ -public boolean equals(Object object) { - if (object == this) return true; - if (!(object instanceof GC)) return false; - return handle == ((GC)object).handle; -} - -/** - * Fills the interior of a circular or elliptical arc within - * the specified rectangular area, with the receiver's background - * color. - * <p> - * The resulting arc begins at <code>startAngle</code> and extends - * for <code>arcAngle</code> degrees, using the current color. - * Angles are interpreted such that 0 degrees is at the 3 o'clock - * position. A positive value indicates a counter-clockwise rotation - * while a negative value indicates a clockwise rotation. - * </p><p> - * The center of the arc is the center of the rectangle whose origin - * is (<code>x</code>, <code>y</code>) and whose size is specified by the - * <code>width</code> and <code>height</code> arguments. - * </p><p> - * The resulting arc covers an area <code>width + 1</code> pixels wide - * by <code>height + 1</code> pixels tall. - * </p> - * - * @param x the x coordinate of the upper-left corner of the arc to be filled - * @param y the y coordinate of the upper-left corner of the arc to be filled - * @param width the width of the arc to be filled - * @param height the height of the arc to be filled - * @param startAngle the beginning angle - * @param arcAngle the angular extent of the arc, relative to the start angle - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #drawArc - */ -public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - checkGC(FILL); - if (data.updateClip) setCGClipping(); - if (width < 0) { - x = x + width; - width = -width; - } - if (height < 0) { - y = y + height; - height = -height; - } - if (width == 0 || height == 0 || arcAngle == 0) return; - OS.CGContextBeginPath(handle); - OS.CGContextSaveGState(handle); - OS.CGContextTranslateCTM(handle, x + width / 2f, y + height / 2f); - OS.CGContextScaleCTM(handle, width / 2f, height / 2f); - OS.CGContextMoveToPoint(handle, 0, 0); - if (arcAngle < 0) { - OS.CGContextAddArc(handle, 0, 0, 1, -(startAngle + arcAngle) * (float)Compatibility.PI / 180, -startAngle * (float)Compatibility.PI / 180, true); - } else { - OS.CGContextAddArc(handle, 0, 0, 1, -startAngle * (float)Compatibility.PI / 180, -(startAngle + arcAngle) * (float)Compatibility.PI / 180, true); - } - OS.CGContextClosePath(handle); - OS.CGContextRestoreGState(handle); - OS.CGContextFillPath(handle); - flush(); -} - -/** - * Fills the interior of the specified rectangle with a gradient - * sweeping from left to right or top to bottom progressing - * from the receiver's foreground color to its background color. - * - * @param x the x coordinate of the rectangle to be filled - * @param y the y coordinate of the rectangle to be filled - * @param width the width of the rectangle to be filled, may be negative - * (inverts direction of gradient if horizontal) - * @param height the height of the rectangle to be filled, may be negative - * (inverts direction of gradient if vertical) - * @param vertical if true sweeps from top to bottom, else - * sweeps from left to right - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #drawRectangle(int, int, int, int) - */ -public void fillGradientRectangle(int x, int y, int width, int height, boolean vertical) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if ((width == 0) || (height == 0)) return; - - /* Rewrite this to use GdkPixbuf */ - - RGB backgroundRGB, foregroundRGB; - backgroundRGB = getBackground().getRGB(); - foregroundRGB = getForeground().getRGB(); - - RGB fromRGB, toRGB; - fromRGB = foregroundRGB; - toRGB = backgroundRGB; - boolean swapColors = false; - if (width < 0) { - x += width; width = -width; - if (! vertical) swapColors = true; - } - if (height < 0) { - y += height; height = -height; - if (vertical) swapColors = true; - } - if (swapColors) { - fromRGB = backgroundRGB; - toRGB = foregroundRGB; - } - if (fromRGB.equals(toRGB)) { - fillRectangle(x, y, width, height); - return; - } - ImageData.fillGradientRectangle(this, data.device, - x, y, width, height, vertical, fromRGB, toRGB, - 8, 8, 8); -} - -/** - * Fills the interior of an oval, within the specified - * rectangular area, with the receiver's background - * color. - * - * @param x the x coordinate of the upper left corner of the oval to be filled - * @param y the y coordinate of the upper left corner of the oval to be filled - * @param width the width of the oval to be filled - * @param height the height of the oval to be filled - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #drawOval - */ -public void fillOval(int x, int y, int width, int height) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - checkGC(FILL); - if (data.updateClip) setCGClipping(); - if (width < 0) { - x = x + width; - width = -width; - } - if (height < 0) { - y = y + height; - height = -height; - } - OS.CGContextBeginPath(handle); - OS.CGContextSaveGState(handle); - OS.CGContextTranslateCTM(handle, x + width / 2f, y + height / 2f); - OS.CGContextScaleCTM(handle, width / 2f, height / 2f); - OS.CGContextMoveToPoint(handle, 1, 0); - OS.CGContextAddArc(handle, 0, 0, 1, 0, (float)(Compatibility.PI * 2), false); - OS.CGContextClosePath(handle); - OS.CGContextRestoreGState(handle); - OS.CGContextFillPath(handle); - flush(); -} - -/** - * Fills the path described by the parameter. - * <p> - * This operation requires the operating system's advanced - * graphics subsystem which may not be available on some - * platforms. - * </p> - * - * @param path the path to fill - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the parameter is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the parameter has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> - * </ul> - * - * @see Path - * - * @since 3.1 - */ -public void fillPath(Path path) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (path == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (path.handle == 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - checkGC(FILL); - if (data.updateClip) setCGClipping(); - OS.CGContextBeginPath(handle); - OS.CGContextAddPath(handle, path.handle); - if (data.fillRule == SWT.FILL_WINDING) { - OS.CGContextFillPath(handle); - } else { - OS.CGContextEOFillPath(handle); - } - flush(); -} - -/** - * Fills the interior of the closed polygon which is defined by the - * specified array of integer coordinates, using the receiver's - * background color. The array contains alternating x and y values - * which are considered to represent points which are the vertices of - * the polygon. Lines are drawn between each consecutive pair, and - * between the first pair and last pair in the array. - * - * @param pointArray an array of alternating x and y values which are the vertices of the polygon - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT if pointArray is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #drawPolygon - */ -public void fillPolygon(int[] pointArray) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (pointArray == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - checkGC(FILL); - if (data.updateClip) setCGClipping(); - float[] points = new float[pointArray.length]; - for (int i=0; i<points.length; i++) { - points[i] = pointArray[i]; - } - OS.CGContextBeginPath(handle); - OS.CGContextAddLines(handle, points, points.length / 2); - OS.CGContextClosePath(handle); - if (data.fillRule == SWT.FILL_WINDING) { - OS.CGContextFillPath(handle); - } else { - OS.CGContextEOFillPath(handle); - } - flush(); -} - -/** - * Fills the interior of the rectangle specified by the arguments, - * using the receiver's background color. - * - * @param x the x coordinate of the rectangle to be filled - * @param y the y coordinate of the rectangle to be filled - * @param width the width of the rectangle to be filled - * @param height the height of the rectangle to be filled - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #drawRectangle(int, int, int, int) - */ -public void fillRectangle(int x, int y, int width, int height) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - checkGC(FILL); - if (data.updateClip) setCGClipping(); - if (width < 0) { - x = x + width; - width = -width; - } - if (height < 0) { - y = y + height; - height = -height; - } - CGRect rect = new CGRect(); - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - Pattern pattern = data.backgroundPattern; - if (pattern != null) pattern.drawRect = rect; - OS.CGContextFillRect(handle, rect); - if (pattern != null) pattern.drawRect = null; - flush(); -} - -/** - * Fills the interior of the specified rectangle, using the receiver's - * background color. - * - * @param rect the rectangle to be filled - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the rectangle is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #drawRectangle(int, int, int, int) - */ -public void fillRectangle(Rectangle rect) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (rect == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - fillRectangle(rect.x, rect.y, rect.width, rect.height); -} - -/** - * Fills the interior of the round-cornered rectangle specified by - * the arguments, using the receiver's background color. - * - * @param x the x coordinate of the rectangle to be filled - * @param y the y coordinate of the rectangle to be filled - * @param width the width of the rectangle to be filled - * @param height the height of the rectangle to be filled - * @param arcWidth the width of the arc - * @param arcHeight the height of the arc - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #drawRoundRectangle - */ -public void fillRoundRectangle(int x, int y, int width, int height, int arcWidth, int arcHeight) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - checkGC(FILL); - if (data.updateClip) setCGClipping(); - if (arcWidth == 0 || arcHeight == 0) { - fillRectangle(x, y, width, height); - return; - } - int nx = x; - int ny = y; - int nw = width; - int nh = height; - int naw = arcWidth; - int nah = arcHeight; - if (nw < 0) { - nw = 0 - nw; - nx = nx - nw; - } - if (nh < 0) { - nh = 0 - nh; - ny = ny - nh; - } - if (naw < 0) naw = 0 - naw; - if (nah < 0) nah = 0 - nah; - if (naw > nw) naw = nw; - if (nah > nh) nah = nh; - float naw2 = naw / 2f; - float nah2 = nah / 2f; - float fw = nw / naw2; - float fh = nh / nah2; - OS.CGContextBeginPath(handle); - OS.CGContextSaveGState(handle); - OS.CGContextTranslateCTM(handle, nx, ny); - OS.CGContextScaleCTM(handle, naw2, nah2); - OS.CGContextMoveToPoint(handle, fw - 1, 0); - OS.CGContextAddArcToPoint(handle, 0, 0, 0, 1, 1); - OS.CGContextAddArcToPoint(handle, 0, fh, 1, fh, 1); - OS.CGContextAddArcToPoint(handle, fw, fh, fw, fh - 1, 1); - OS.CGContextAddArcToPoint(handle, fw, 0, fw - 1, 0, 1); - OS.CGContextClosePath(handle); - OS.CGContextRestoreGState(handle); - OS.CGContextFillPath(handle); - flush(); -} - -void flush () { - if (data.control != 0 && data.paintEvent == 0) { - if (data.thread != Thread.currentThread()) { - OS.CGContextFlush(handle); - } else { - OS.CGContextSynchronize(handle); - } - } - if (data.control == 0 && data.window != 0) OS.CGContextSynchronize(handle); -} - -/** - * Returns the <em>advance width</em> of the specified character in - * the font which is currently selected into the receiver. - * <p> - * The advance width is defined as the horizontal distance the cursor - * should move after printing the character in the selected font. - * </p> - * - * @param ch the character to measure - * @return the distance in the x direction to move past the character before painting the next - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public int getAdvanceWidth(char ch) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - //NOT DONE - return stringExtent(new String(new char[]{ch})).x; -} - -/** - * Returns the background color. - * - * @return the receiver's background color - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public Color getBackground() { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - return Color.carbon_new (data.device, data.background); -} - -/** - * Returns the background pattern. The default value is - * <code>null</code>. - * - * @return the receiver's background pattern - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see Pattern - * - * @since 3.1 - */ -public Pattern getBackgroundPattern() { - if (handle == 0) SWT.error(SWT.ERROR_WIDGET_DISPOSED); - return data.backgroundPattern; -} - -/** - * Returns <code>true</code> if receiver is using the operating system's - * advanced graphics subsystem. Otherwise, <code>false</code> is returned - * to indicate that normal graphics are in use. - * <p> - * Advanced graphics may not be installed for the operating system. In this - * case, <code>false</code> is always returned. Some operating system have - * only one graphics subsystem. If this subsystem supports advanced graphics, - * then <code>true</code> is always returned. If any graphics operation such - * as alpha, antialias, patterns, interpolation, paths, clipping or transformation - * has caused the receiver to switch from regular to advanced graphics mode, - * <code>true</code> is returned. If the receiver has been explicitly switched - * to advanced mode and this mode is supported, <code>true</code> is returned. - * </p> - * - * @return the advanced value - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #setAdvanced - * - * @since 3.1 - */ -public boolean getAdvanced() { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - return true; -} - -/** - * Returns the receiver's alpha value. The alpha value - * is between 0 (transparent) and 255 (opaque). - * - * @return the alpha value - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.1 - */ -public int getAlpha() { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - return data.alpha; -} - -/** - * Returns the receiver's anti-aliasing setting value, which will be - * one of <code>SWT.DEFAULT</code>, <code>SWT.OFF</code> or - * <code>SWT.ON</code>. Note that this controls anti-aliasing for all - * <em>non-text drawing</em> operations. - * - * @return the anti-aliasing setting - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #getTextAntialias - * - * @since 3.1 - */ -public int getAntialias() { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - return data.antialias; -} - -/** - * Returns the width of the specified character in the font - * selected into the receiver. - * <p> - * The width is defined as the space taken up by the actual - * character, not including the leading and tailing whitespace - * or overhang. - * </p> - * - * @param ch the character to measure - * @return the width of the character - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public int getCharWidth(char ch) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - //NOT DONE - return stringExtent(new String(new char[]{ch})).x; -} - -/** - * Returns the bounding rectangle of the receiver's clipping - * region. If no clipping region is set, the return value - * will be a rectangle which covers the entire bounds of the - * object the receiver is drawing on. - * - * @return the bounding rectangle of the clipping region - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public Rectangle getClipping() { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - /* Calculate visible bounds in device space*/ - Rect rect = null; - int x = 0, y = 0, width = 0, height = 0; - if (data.control != 0) { - if (rect == null) rect = new Rect(); - OS.GetControlBounds(data.control, rect); - width = rect.right - rect.left; - height = rect.bottom - rect.top; - } else { - if (data.image != null) { - int image = data.image.handle; - width = OS.CGImageGetWidth(image); - height = OS.CGImageGetHeight(image); - } else if (data.portRect != null) { - width = data.portRect.right - data.portRect.left; - height = data.portRect.bottom - data.portRect.top; - } - } - /* Intersect visible bounds with clipping in device space and then convert the user space */ - int clipRgn = data.clipRgn; - int visibleRgn = data.visibleRgn; - if (clipRgn != 0 || visibleRgn != 0 || data.inverseTransform != null) { - int rgn = OS.NewRgn(); - OS.SetRectRgn(rgn, (short)x, (short)y, (short)(x + width), (short)(y + height)); - if (visibleRgn != 0) { - OS.SectRgn(rgn, visibleRgn, rgn); - } - /* Intersect visible bounds with clipping */ - if (clipRgn != 0) { - /* Convert clipping to device space if needed */ - if (data.clippingTransform != null) { - clipRgn = convertRgn(clipRgn, data.clippingTransform); - OS.SectRgn(rgn, clipRgn, rgn); - OS.DisposeRgn(clipRgn); - } else { - OS.SectRgn(rgn, clipRgn, rgn); - } - } - /* Convert to user space */ - if (data.inverseTransform != null) { - clipRgn = convertRgn(rgn, data.inverseTransform); - OS.DisposeRgn(rgn); - rgn = clipRgn; - } - if (rect == null) rect = new Rect(); - OS.GetRegionBounds(rgn, rect); - OS.DisposeRgn(rgn); - x = rect.left; - y = rect.top; - width = rect.right - rect.left; - height = rect.bottom - rect.top; - } - return new Rectangle(x, y, width, height); -} - -/** - * Sets the region managed by the argument to the current - * clipping region of the receiver. - * - * @param region the region to fill with the clipping region - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the region is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the region is disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void getClipping(Region region) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (region == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (region.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - Rect bounds = null; - int clipping = region.handle; - if (data.clipRgn == 0) { - int width = 0, height = 0; - if (data.control != 0) { - if (bounds == null) bounds = new Rect(); - OS.GetControlBounds(data.control, bounds); - width = bounds.right - bounds.left; - height = bounds.bottom - bounds.top; - } else { - if (data.image != null) { - int image = data.image.handle; - width = OS.CGImageGetWidth(image); - height = OS.CGImageGetHeight(image); - } else if (data.portRect != null) { - width = data.portRect.right - data.portRect.left; - height = data.portRect.bottom - data.portRect.top; - } - } - OS.SetRectRgn(clipping, (short)0, (short)0, (short)width, (short)height); - } else { - /* Convert clipping to device space if needed */ - if (data.clippingTransform != null) { - int rgn = convertRgn(data.clipRgn, data.clippingTransform); - OS.CopyRgn(rgn, clipping); - OS.DisposeRgn(rgn); - } else { - OS.CopyRgn(data.clipRgn, clipping); - } - } - if (data.paintEvent != 0 && data.visibleRgn != 0) { - if (bounds == null) bounds = new Rect(); - OS.GetControlBounds(data.control, bounds); - if (data.paintEvent == 0) OS.OffsetRgn(data.visibleRgn, (short)-bounds.left, (short)-bounds.top); - OS.SectRgn(data.visibleRgn, clipping, clipping); - if (data.paintEvent == 0) OS.OffsetRgn(data.visibleRgn, bounds.left, bounds.top); - } - /* Convert to user space */ - if (data.inverseTransform != null) { - int rgn = convertRgn(clipping, data.inverseTransform); - OS.CopyRgn(rgn, clipping); - OS.DisposeRgn(rgn); - } -} - -/** - * Returns the receiver's fill rule, which will be one of - * <code>SWT.FILL_EVEN_ODD</code> or <code>SWT.FILL_WINDING</code>. - * - * @return the receiver's fill rule - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.1 - */ -public int getFillRule() { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - return data.fillRule; -} - -/** - * Returns the font currently being used by the receiver - * to draw and measure text. - * - * @return the receiver's font - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public Font getFont() { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - return data.font; -} - -/** - * Returns a FontMetrics which contains information - * about the font currently being used by the receiver - * to draw and measure text. - * - * @return font metrics for the receiver's font - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public FontMetrics getFontMetrics() { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - checkGC(FONT); - Font font = data.font; - ATSFontMetrics metrics = new ATSFontMetrics(); - OS.ATSFontGetVerticalMetrics(font.handle, OS.kATSOptionFlagsDefault, metrics); - OS.ATSFontGetHorizontalMetrics(font.handle, OS.kATSOptionFlagsDefault, metrics); - int ascent = (int)(0.5f + metrics.ascent * font.size); - int descent = (int)(0.5f + (-metrics.descent + metrics.leading) * font.size); - String s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - int averageCharWidth = stringExtent(s).x / s.length(); - return FontMetrics.carbon_new(ascent, descent, averageCharWidth, 0, ascent + descent); -} - -/** - * Returns the receiver's foreground color. - * - * @return the color used for drawing foreground things - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public Color getForeground() { - if (handle == 0) SWT.error(SWT.ERROR_WIDGET_DISPOSED); - return Color.carbon_new(data.device, data.foreground); -} - -/** - * Returns the foreground pattern. The default value is - * <code>null</code>. - * - * @return the receiver's foreground pattern - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see Pattern - * - * @since 3.1 - */ -public Pattern getForegroundPattern() { - if (handle == 0) SWT.error(SWT.ERROR_WIDGET_DISPOSED); - return data.foregroundPattern; -} - -/** - * Returns the GCData. - * <p> - * <b>IMPORTANT:</b> This method is <em>not</em> part of the public - * API for <code>GC</code>. It is marked public only so that it - * can be shared within the packages provided by SWT. It is not - * available on all platforms, and should never be called from - * application code. - * </p> - * - * @return the receiver's GCData - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see GCData - * - * @since 3.2 - * @noreference This method is not intended to be referenced by clients. - */ -public GCData getGCData() { - if (handle == 0) SWT.error(SWT.ERROR_WIDGET_DISPOSED); - return data; -} - -/** - * Returns the receiver's interpolation setting, which will be one of - * <code>SWT.DEFAULT</code>, <code>SWT.NONE</code>, - * <code>SWT.LOW</code> or <code>SWT.HIGH</code>. - * - * @return the receiver's interpolation setting - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.1 - */ -public int getInterpolation() { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - int interpolation = OS.CGContextGetInterpolationQuality(handle); - switch (interpolation) { - case OS.kCGInterpolationDefault: return SWT.DEFAULT; - case OS.kCGInterpolationNone: return SWT.NONE; - case OS.kCGInterpolationLow: return SWT.LOW; - case OS.kCGInterpolationHigh: return SWT.HIGH; - } - return SWT.DEFAULT; -} - -/** - * Returns the receiver's line attributes. - * - * @return the line attributes used for drawing lines - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.3 - */ -public LineAttributes getLineAttributes() { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - float[] dashes = null; - if (data.lineDashes != null) { - dashes = new float[data.lineDashes.length]; - System.arraycopy(data.lineDashes, 0, dashes, 0, dashes.length); - } - return new LineAttributes(data.lineWidth, data.lineCap, data.lineJoin, data.lineStyle, dashes, data.lineDashesOffset, data.lineMiterLimit); -} - -/** - * Returns the receiver's line cap style, which will be one - * of the constants <code>SWT.CAP_FLAT</code>, <code>SWT.CAP_ROUND</code>, - * or <code>SWT.CAP_SQUARE</code>. - * - * @return the cap style used for drawing lines - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.1 - */ -public int getLineCap() { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - return data.lineCap; -} - -/** - * Returns the receiver's line dash style. The default value is - * <code>null</code>. - * - * @return the line dash style used for drawing lines - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.1 - */ -public int[] getLineDash() { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (data.lineDashes == null) return null; - int[] lineDashes = new int[data.lineDashes.length]; - for (int i = 0; i < lineDashes.length; i++) { - lineDashes[i] = (int)data.lineDashes[i]; - } - return lineDashes; -} - -/** - * Returns the receiver's line join style, which will be one - * of the constants <code>SWT.JOIN_MITER</code>, <code>SWT.JOIN_ROUND</code>, - * or <code>SWT.JOIN_BEVEL</code>. - * - * @return the join style used for drawing lines - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.1 - */ -public int getLineJoin() { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - return data.lineJoin; -} - -/** - * Returns the receiver's line style, which will be one - * of the constants <code>SWT.LINE_SOLID</code>, <code>SWT.LINE_DASH</code>, - * <code>SWT.LINE_DOT</code>, <code>SWT.LINE_DASHDOT</code> or - * <code>SWT.LINE_DASHDOTDOT</code>. - * - * @return the style used for drawing lines - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public int getLineStyle() { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - return data.lineStyle; -} - -/** - * Returns the width that will be used when drawing lines - * for all of the figure drawing operations (that is, - * <code>drawLine</code>, <code>drawRectangle</code>, - * <code>drawPolyline</code>, and so forth. - * - * @return the receiver's line width - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public int getLineWidth() { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - return (int)data.lineWidth; -} - -/** - * Returns the receiver's style information. - * <p> - * Note that the value which is returned by this method <em>may - * not match</em> the value which was provided to the constructor - * when the receiver was created. This can occur when the underlying - * operating system does not support a particular combination of - * requested styles. - * </p> - * - * @return the style bits - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 2.1.2 - */ -public int getStyle () { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - return data.style; -} - -/** - * Returns the receiver's text drawing anti-aliasing setting value, - * which will be one of <code>SWT.DEFAULT</code>, <code>SWT.OFF</code> or - * <code>SWT.ON</code>. Note that this controls anti-aliasing - * <em>only</em> for text drawing operations. - * - * @return the anti-aliasing setting - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #getAntialias - * - * @since 3.1 - */ -public int getTextAntialias() { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - return data.textAntialias; -} - -/** - * Sets the parameter to the transform that is currently being - * used by the receiver. - * - * @param transform the destination to copy the transform into - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the parameter is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the parameter has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see Transform - * - * @since 3.1 - */ -public void getTransform (Transform transform) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (transform == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (transform.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - float[] cmt = data.transform; - if (cmt != null) { - transform.setElements(cmt[0], cmt[1], cmt[2], cmt[3], cmt[4], cmt[5]); - } else { - transform.setElements(1, 0, 0, 1, 0, 0); - } -} - -/** - * Returns <code>true</code> if this GC is drawing in the mode - * where the resulting color in the destination is the - * <em>exclusive or</em> of the color values in the source - * and the destination, and <code>false</code> if it is - * drawing in the mode where the destination color is being - * replaced with the source color value. - * - * @return <code>true</code> true if the receiver is in XOR mode, and false otherwise - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public boolean getXORMode() { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - return data.xorMode; -} - -/** - * Returns an integer hash code for the receiver. Any two - * objects that return <code>true</code> when passed to - * <code>equals</code> must return the same value for this - * method. - * - * @return the receiver's hash - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #equals - */ -public int hashCode() { - return handle; -} - -void init(Drawable drawable, GCData data, int context) { - if (data.foreground != null) data.state &= ~(FOREGROUND | FOREGROUND_FILL); - if (data.background != null) data.state &= ~BACKGROUND; - if (data.font != null) data.state &= ~FONT; - data.state &= ~DRAW_OFFSET; - - Image image = data.image; - if (image != null) image.memGC = this; - this.drawable = drawable; - this.data = data; - handle = context; - -} - -/** - * Returns <code>true</code> if the receiver has a clipping - * region set into it, and <code>false</code> otherwise. - * If this method returns false, the receiver will draw on all - * available space in the destination. If it returns true, - * it will draw only in the area that is covered by the region - * that can be accessed with <code>getClipping(region)</code>. - * - * @return <code>true</code> if the GC has a clipping region, and <code>false</code> otherwise - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public boolean isClipped() { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - return data.clipRgn != 0; -} - -/** - * Returns <code>true</code> if the GC has been disposed, - * and <code>false</code> otherwise. - * <p> - * This method gets the dispose state for the GC. - * When a GC has been disposed, it is an error to - * invoke any other method using the GC. - * - * @return <code>true</code> when the GC is disposed and <code>false</code> otherwise - */ -public boolean isDisposed() { - return handle == 0; -} - -boolean isIdentity(float[] transform) { - return transform[0] == 1 && transform[1] == 0 && transform[2] == 0 - && transform[3] == 1 && transform[4] == 0 && transform[5] == 0; -} - -/** - * Sets the receiver to always use the operating system's advanced graphics - * subsystem for all graphics operations if the argument is <code>true</code>. - * If the argument is <code>false</code>, the advanced graphics subsystem is - * no longer used, advanced graphics state is cleared and the normal graphics - * subsystem is used from now on. - * <p> - * Normally, the advanced graphics subsystem is invoked automatically when - * any one of the alpha, antialias, patterns, interpolation, paths, clipping - * or transformation operations in the receiver is requested. When the receiver - * is switched into advanced mode, the advanced graphics subsystem performs both - * advanced and normal graphics operations. Because the two subsystems are - * different, their output may differ. Switching to advanced graphics before - * any graphics operations are performed ensures that the output is consistent. - * </p><p> - * Advanced graphics may not be installed for the operating system. In this - * case, this operation does nothing. Some operating system have only one - * graphics subsystem, so switching from normal to advanced graphics does - * nothing. However, switching from advanced to normal graphics will always - * clear the advanced graphics state, even for operating systems that have - * only one graphics subsystem. - * </p> - * - * @param advanced the new advanced graphics state - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #setAlpha - * @see #setAntialias - * @see #setBackgroundPattern - * @see #setClipping(Path) - * @see #setForegroundPattern - * @see #setLineAttributes - * @see #setInterpolation - * @see #setTextAntialias - * @see #setTransform - * @see #getAdvanced - * - * @since 3.1 - */ -public void setAdvanced(boolean advanced) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (!advanced) { - setAlpha(0xFF); - setAntialias(SWT.DEFAULT); - setBackgroundPattern(null); - setClipping(0); - setForegroundPattern(null); - setInterpolation(SWT.DEFAULT); - setTextAntialias(SWT.DEFAULT); - setTransform(null); - } -} - -/** - * Sets the receiver's alpha value which must be - * between 0 (transparent) and 255 (opaque). - * <p> - * This operation requires the operating system's advanced - * graphics subsystem which may not be available on some - * platforms. - * </p> - * @param alpha the alpha value - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> - * </ul> - * - * @see #getAdvanced - * @see #setAdvanced - * - * @since 3.1 - */ -public void setAlpha(int alpha) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - data.alpha = alpha & 0xFF; - OS.CGContextSetAlpha(handle, data.alpha / 255f); -} - -/** - * Sets the receiver's anti-aliasing value to the parameter, - * which must be one of <code>SWT.DEFAULT</code>, <code>SWT.OFF</code> - * or <code>SWT.ON</code>. Note that this controls anti-aliasing for all - * <em>non-text drawing</em> operations. - * <p> - * This operation requires the operating system's advanced - * graphics subsystem which may not be available on some - * platforms. - * </p> - * - * @param antialias the anti-aliasing setting - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the parameter is not one of <code>SWT.DEFAULT</code>, - * <code>SWT.OFF</code> or <code>SWT.ON</code></li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> - * </ul> - * - * @see #getAdvanced - * @see #setAdvanced - * @see #setTextAntialias - * - * @since 3.1 - */ -public void setAntialias(int antialias) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - boolean mode = true; - switch (antialias) { - case SWT.DEFAULT: - /* Printer is off by default */ - if (data.window == 0 && data.control == 0 && data.image == null) mode = false; - break; - case SWT.OFF: mode = false; break; - case SWT.ON: mode = true; break; - default: - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - data.antialias = antialias; - OS.CGContextSetShouldAntialias(handle, mode); -} - -/** - * Sets the background color. The background color is used - * for fill operations and as the background color when text - * is drawn. - * - * @param color the new background color for the receiver - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the color is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the color has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void setBackground(Color color) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (color == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (color.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - data.background = color.handle; - if (data.backPattern != 0) OS.CGPatternRelease(data.backPattern); - data.backPattern = 0; - data.backgroundPattern = null; - data.state &= ~BACKGROUND; -} - -/** - * Sets the background pattern. The default value is <code>null</code>. - * <p> - * This operation requires the operating system's advanced - * graphics subsystem which may not be available on some - * platforms. - * </p> - * - * @param pattern the new background pattern - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the parameter has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> - * </ul> - * - * @see Pattern - * @see #getAdvanced - * @see #setAdvanced - * - * @since 3.1 - */ -public void setBackgroundPattern(Pattern pattern) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (pattern != null && pattern.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - if (data.backgroundPattern == pattern) return; - if (data.backPattern != 0) OS.CGPatternRelease(data.backPattern); - data.backPattern = 0; - data.backgroundPattern = pattern; - data.state &= ~BACKGROUND; -} - -void setClipping(int clipRgn) { - if (clipRgn == 0) { - if (data.clipRgn != 0) { - OS.DisposeRgn(data.clipRgn); - data.clipRgn = 0; - } - data.clippingTransform = null; - } else { - if (data.clipRgn == 0) data.clipRgn = OS.NewRgn(); - OS.CopyRgn(clipRgn, data.clipRgn); - if (data.transform != null) { - if (data.clippingTransform == null) data.clippingTransform = new float[6]; - System.arraycopy(data.transform, 0, data.clippingTransform, 0, data.transform.length); - } - } - data.updateClip = true; - setCGClipping(); -} - -/** - * Sets the area of the receiver which can be changed - * by drawing operations to the rectangular area specified - * by the arguments. - * - * @param x the x coordinate of the clipping rectangle - * @param y the y coordinate of the clipping rectangle - * @param width the width of the clipping rectangle - * @param height the height of the clipping rectangle - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void setClipping(int x, int y, int width, int height) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (width < 0) { - x = x + width; - width = -width; - } - if (height < 0) { - y = y + height; - height = -height; - } - int clipRgn = OS.NewRgn(); - OS.SetRectRgn(clipRgn, (short)x, (short)y, (short)(x + width), (short)(y + height)); - setClipping(clipRgn); - OS.DisposeRgn(clipRgn); -} - -/** - * Sets the area of the receiver which can be changed - * by drawing operations to the path specified - * by the argument. - * <p> - * This operation requires the operating system's advanced - * graphics subsystem which may not be available on some - * platforms. - * </p> - * - * @param path the clipping path. - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the path has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> - * </ul> - * - * @see Path - * @see #getAdvanced - * @see #setAdvanced - * - * @since 3.1 - */ -public void setClipping(Path path) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (path != null && path.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - setClipping(0); - if (path != null) { - OS.CGContextAddPath(handle, path.handle); - OS.CGContextEOClip(handle); - } -} - -/** - * Sets the area of the receiver which can be changed - * by drawing operations to the rectangular area specified - * by the argument. Specifying <code>null</code> for the - * rectangle reverts the receiver's clipping area to its - * original value. - * - * @param rect the clipping rectangle or <code>null</code> - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void setClipping(Rectangle rect) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (rect == null) { - setClipping(0); - } else { - setClipping(rect.x, rect.y, rect.width, rect.height); - } -} - -/** - * Sets the area of the receiver which can be changed - * by drawing operations to the region specified - * by the argument. Specifying <code>null</code> for the - * region reverts the receiver's clipping area to its - * original value. - * - * @param region the clipping region or <code>null</code> - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the region has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void setClipping(Region region) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (region != null && region.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - setClipping(region != null ? region.handle : 0); -} - -void setCGClipping () { - data.updateClip = false; - if (data.control == 0) { - if (data.window != 0 && ! OS.IsWindowVisible(data.window)) OS.ShowWindow (data.window); - OS.CGContextScaleCTM(handle, 1, -1); - if (data.clipRgn != 0) { - OS.ClipCGContextToRegion(handle, new Rect(), data.clipRgn); - } else { - int rgn = OS.NewRgn(); - OS.SetRectRgn(rgn, (short)-32768, (short)-32768, (short)32767, (short)32767); - OS.ClipCGContextToRegion(handle, new Rect(), rgn); - OS.DisposeRgn(rgn); - } - OS.CGContextScaleCTM(handle, 1, -1); - return; - } - int port = data.port; - int window = OS.GetControlOwner(data.control); - if (port == 0) { - port = OS.GetWindowPort(window); - } - Rect portRect = data.portRect; - Rect rect = data.controlRect; - OS.CGContextTranslateCTM(handle, -rect.left, (portRect.bottom - portRect.top) - rect.top); - OS.CGContextScaleCTM(handle, 1, -1); - OS.GetPortBounds(port, portRect); - OS.GetControlBounds(data.control, rect); - boolean isPaint = data.paintEvent != 0; - if (isPaint) { - rect.right += rect.left; - rect.bottom += rect.top; - rect.left = rect.top = 0; - } else { - int [] contentView = new int [1]; - OS.HIViewFindByID (OS.HIViewGetRoot (window), OS.kHIViewWindowContentID (), contentView); - CGPoint pt = new CGPoint (); - OS.HIViewConvertPoint (pt, OS.HIViewGetSuperview (data.control), contentView [0]); - rect.left += (int) pt.x; - rect.top += (int) pt.y; - rect.right += (int) pt.x; - rect.bottom += (int) pt.y; - } - if (data.clipRgn != 0) { - int rgn = OS.NewRgn(); - OS.CopyRgn(data.clipRgn, rgn); - OS.OffsetRgn(rgn, rect.left, rect.top); - OS.SectRgn(data.visibleRgn, rgn, rgn); - OS.ClipCGContextToRegion(handle, portRect, rgn); - OS.DisposeRgn(rgn); - } else { - OS.ClipCGContextToRegion(handle, portRect, data.visibleRgn); - } - OS.CGContextScaleCTM(handle, 1, -1); - OS.CGContextTranslateCTM(handle, rect.left, -(portRect.bottom - portRect.top) + rect.top); -} - -void setCGFont() { - int tabs = data.tabs; - if (tabs != 0) OS.DisposePtr(tabs); - data.tabs = 0; - Font font = data.font; - ATSFontMetrics metrics = new ATSFontMetrics(); - OS.ATSFontGetVerticalMetrics(font.handle, OS.kATSOptionFlagsDefault, metrics); - OS.ATSFontGetHorizontalMetrics(font.handle, OS.kATSOptionFlagsDefault, metrics); - data.fontAscent = (int)(0.5f + metrics.ascent * font.size); - data.fontDescent = (int)(0.5f + (-metrics.descent + metrics.leading) * font.size); - if (font.atsuiStyle == 0) { - if (data.atsuiStyle != 0) OS.ATSUDisposeStyle(data.atsuiStyle); - data.atsuiStyle = font.createStyle(); - } - data.string = null; - data.stringWidth = data.stringHeight = -1; -} - -/** - * Sets the receiver's fill rule to the parameter, which must be one of - * <code>SWT.FILL_EVEN_ODD</code> or <code>SWT.FILL_WINDING</code>. - * - * @param rule the new fill rule - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the rule is not one of <code>SWT.FILL_EVEN_ODD</code> - * or <code>SWT.FILL_WINDING</code></li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.1 - */ -public void setFillRule(int rule) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - switch (rule) { - case SWT.FILL_WINDING: - case SWT.FILL_EVEN_ODD: break; - default: - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - data.fillRule = rule; -} - -/** - * Sets the font which will be used by the receiver - * to draw and measure text to the argument. If the - * argument is null, then a default font appropriate - * for the platform will be used instead. - * - * @param font the new font for the receiver, or null to indicate a default font - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the font has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void setFont(Font font) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (font != null && font.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - data.font = font != null ? font : data.device.systemFont; - data.state &= ~FONT; -} - -/** - * Sets the foreground color. The foreground color is used - * for drawing operations including when text is drawn. - * - * @param color the new foreground color for the receiver - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the color is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the color has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void setForeground(Color color) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (color == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (color.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - data.foreground = color.handle; - if (data.forePattern != 0) OS.CGPatternRelease(data.forePattern); - data.forePattern = 0; - data.foregroundPattern = null; - data.state &= ~(FOREGROUND | FOREGROUND_FILL); -} - -/** - * Sets the foreground pattern. The default value is <code>null</code>. - * <p> - * This operation requires the operating system's advanced - * graphics subsystem which may not be available on some - * platforms. - * </p> - * @param pattern the new foreground pattern - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the parameter has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> - * </ul> - * - * @see Pattern - * @see #getAdvanced - * @see #setAdvanced - * - * @since 3.1 - */ -public void setForegroundPattern(Pattern pattern) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (pattern != null && pattern.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - if (data.foregroundPattern == pattern) return; - if (data.forePattern != 0) OS.CGPatternRelease(data.forePattern); - data.forePattern = 0; - data.foregroundPattern = pattern; - data.state &= ~(FOREGROUND | FOREGROUND_FILL); -} - -/** - * Sets the receiver's interpolation setting to the parameter, which - * must be one of <code>SWT.DEFAULT</code>, <code>SWT.NONE</code>, - * <code>SWT.LOW</code> or <code>SWT.HIGH</code>. - * <p> - * This operation requires the operating system's advanced - * graphics subsystem which may not be available on some - * platforms. - * </p> - * - * @param interpolation the new interpolation setting - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the rule is not one of <code>SWT.DEFAULT</code>, - * <code>SWT.NONE</code>, <code>SWT.LOW</code> or <code>SWT.HIGH</code> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> - * </ul> - * - * @see #getAdvanced - * @see #setAdvanced - * - * @since 3.1 - */ -public void setInterpolation(int interpolation) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - int quality = 0; - switch (interpolation) { - case SWT.DEFAULT: quality = OS.kCGInterpolationDefault; break; - case SWT.NONE: quality = OS.kCGInterpolationNone; break; - case SWT.LOW: quality = OS.kCGInterpolationLow; break; - case SWT.HIGH: quality = OS.kCGInterpolationHigh; break; - default: - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - OS.CGContextSetInterpolationQuality(handle, quality); -} - -/** - * Sets the receiver's line attributes. - * <p> - * This operation requires the operating system's advanced - * graphics subsystem which may not be available on some - * platforms. - * </p> - * @param attributes the line attributes - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the attributes is null</li> - * <li>ERROR_INVALID_ARGUMENT - if any of the line attributes is not valid</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> - * </ul> - * - * @see LineAttributes - * @see #getAdvanced - * @see #setAdvanced - * - * @since 3.3 - */ -public void setLineAttributes(LineAttributes attributes) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (attributes == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - int mask = 0; - float lineWidth = attributes.width; - if (lineWidth != data.lineWidth) { - mask |= LINE_WIDTH | DRAW_OFFSET; - } - int lineStyle = attributes.style; - if (lineStyle != data.lineStyle) { - mask |= LINE_STYLE; - switch (lineStyle) { - case SWT.LINE_SOLID: - case SWT.LINE_DASH: - case SWT.LINE_DOT: - case SWT.LINE_DASHDOT: - case SWT.LINE_DASHDOTDOT: - break; - case SWT.LINE_CUSTOM: - if (attributes.dash == null) lineStyle = SWT.LINE_SOLID; - break; - default: - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - } - int join = attributes.join; - if (join != data.lineJoin) { - mask |= LINE_JOIN; - switch (join) { - case SWT.CAP_ROUND: - case SWT.CAP_FLAT: - case SWT.CAP_SQUARE: - break; - default: - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - } - int cap = attributes.cap; - if (cap != data.lineCap) { - mask |= LINE_CAP; - switch (cap) { - case SWT.JOIN_MITER: - case SWT.JOIN_ROUND: - case SWT.JOIN_BEVEL: - break; - default: - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - } - float[] dashes = attributes.dash; - float[] lineDashes = data.lineDashes; - if (dashes != null && dashes.length > 0) { - boolean changed = lineDashes == null || lineDashes.length != dashes.length; - for (int i = 0; i < dashes.length; i++) { - float dash = dashes[i]; - if (dash <= 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - if (!changed && lineDashes[i] != dash) changed = true; - } - if (changed) { - float[] newDashes = new float[dashes.length]; - System.arraycopy(dashes, 0, newDashes, 0, dashes.length); - dashes = newDashes; - mask |= LINE_STYLE; - } else { - dashes = lineDashes; - } - } else { - if (lineDashes != null && lineDashes.length > 0) { - mask |= LINE_STYLE; - } else { - dashes = lineDashes; - } - } - float dashOffset = attributes.dashOffset; - if (dashOffset != data.lineDashesOffset) { - mask |= LINE_STYLE; - } - float miterLimit = attributes.miterLimit; - if (miterLimit != data.lineMiterLimit) { - mask |= LINE_MITERLIMIT; - } - if (mask == 0) return; - data.lineWidth = lineWidth; - data.lineStyle = lineStyle; - data.lineCap = cap; - data.lineJoin = join; - data.lineDashes = dashes; - data.lineDashesOffset = dashOffset; - data.lineMiterLimit = miterLimit; - data.state &= ~mask; -} - -/** - * Sets the receiver's line cap style to the argument, which must be one - * of the constants <code>SWT.CAP_FLAT</code>, <code>SWT.CAP_ROUND</code>, - * or <code>SWT.CAP_SQUARE</code>. - * - * @param cap the cap style to be used for drawing lines - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the style is not valid</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.1 - */ -public void setLineCap(int cap) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (data.lineCap == cap) return; - switch (cap) { - case SWT.CAP_ROUND: - case SWT.CAP_FLAT: - case SWT.CAP_SQUARE: - break; - default: - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - data.lineCap = cap; - data.state &= ~LINE_CAP; -} - -/** - * Sets the receiver's line dash style to the argument. The default - * value is <code>null</code>. If the argument is not <code>null</code>, - * the receiver's line style is set to <code>SWT.LINE_CUSTOM</code>, otherwise - * it is set to <code>SWT.LINE_SOLID</code>. - * - * @param dashes the dash style to be used for drawing lines - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if any of the values in the array is less than or equal 0</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.1 - */ -public void setLineDash(int[] dashes) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - float[] lineDashes = data.lineDashes; - if (dashes != null && dashes.length > 0) { - boolean changed = data.lineStyle != SWT.LINE_CUSTOM || lineDashes == null || lineDashes.length != dashes.length; - for (int i = 0; i < dashes.length; i++) { - int dash = dashes[i]; - if (dash <= 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - if (!changed && lineDashes[i] != dash) changed = true; - } - if (!changed) return; - data.lineDashes = new float[dashes.length]; - for (int i = 0; i < dashes.length; i++) { - data.lineDashes[i] = dashes[i]; - } - data.lineStyle = SWT.LINE_CUSTOM; - } else { - if (data.lineStyle == SWT.LINE_SOLID && (lineDashes == null || lineDashes.length == 0)) return; - data.lineDashes = null; - data.lineStyle = SWT.LINE_SOLID; - } - data.state &= ~LINE_STYLE; -} - -/** - * Sets the receiver's line join style to the argument, which must be one - * of the constants <code>SWT.JOIN_MITER</code>, <code>SWT.JOIN_ROUND</code>, - * or <code>SWT.JOIN_BEVEL</code>. - * - * @param join the join style to be used for drawing lines - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the style is not valid</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.1 - */ -public void setLineJoin(int join) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (data.lineJoin == join) return; - switch (join) { - case SWT.JOIN_MITER: - case SWT.JOIN_ROUND: - case SWT.JOIN_BEVEL: - break; - default: - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - data.lineJoin = join; - data.state &= ~LINE_JOIN; -} - -/** - * Sets the receiver's line style to the argument, which must be one - * of the constants <code>SWT.LINE_SOLID</code>, <code>SWT.LINE_DASH</code>, - * <code>SWT.LINE_DOT</code>, <code>SWT.LINE_DASHDOT</code> or - * <code>SWT.LINE_DASHDOTDOT</code>. - * - * @param lineStyle the style to be used for drawing lines - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the style is not valid</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void setLineStyle(int lineStyle) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (data.lineStyle == lineStyle) return; - switch (lineStyle) { - case SWT.LINE_SOLID: - case SWT.LINE_DASH: - case SWT.LINE_DOT: - case SWT.LINE_DASHDOT: - case SWT.LINE_DASHDOTDOT: - break; - case SWT.LINE_CUSTOM: - if (data.lineDashes == null) lineStyle = SWT.LINE_SOLID; - break; - default: - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - data.lineStyle = lineStyle; - data.state &= ~LINE_STYLE; -} - -/** - * Sets the width that will be used when drawing lines - * for all of the figure drawing operations (that is, - * <code>drawLine</code>, <code>drawRectangle</code>, - * <code>drawPolyline</code>, and so forth. - * <p> - * Note that line width of zero is used as a hint to - * indicate that the fastest possible line drawing - * algorithms should be used. This means that the - * output may be different from line width one. - * </p> - * - * @param lineWidth the width of a line - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void setLineWidth(int lineWidth) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (data.lineWidth == lineWidth) return; - data.lineWidth = lineWidth; - data.state &= ~(LINE_WIDTH | DRAW_OFFSET); -} - -int setString(String string, int flags) { - if (data.layout == 0) createLayout (); - if (string == data.string && (flags & ~SWT.DRAW_TRANSPARENT) == (data.drawFlags & ~SWT.DRAW_TRANSPARENT)) { - return data.stringLength; - } - int layout = data.layout; - int length = string.length(); - char[] chars = new char[length]; - string.getChars(0, length, chars, 0); - int breakCount = 0; - int[] breaks = null; - if ((flags & (SWT.DRAW_MNEMONIC | SWT.DRAW_DELIMITER)) != 0) { - int i=0, j=0; - while (i < chars.length) { - char c = chars [j++] = chars [i++]; - switch (c) { - case '&': { - if ((flags & SWT.DRAW_MNEMONIC) != 0) { - if (i == chars.length) {continue;} - if (chars [i] == '&') {i++; continue;} - j--; - } - break; - } - case '\r': - case '\n': { - if ((flags & SWT.DRAW_DELIMITER) != 0) { - if (c == '\r' && i != chars.length && chars[i] == '\n') i++; - j--; - if (breaks == null) { - breaks = new int[4]; - } else if (breakCount == 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; - } - if ((flags & SWT.DRAW_TAB) != 0) { - if (data.tabs == 0) createTabs(); - OS.ATSUSetTabArray(layout, data.tabs, TAB_COUNT); - } else { - OS.ATSUSetTabArray(layout, 0, 0); - } - int ptr = OS.NewPtr(length * 2); - OS.memmove(ptr, chars, length * 2); - OS.ATSUSetTextPointerLocation(layout, ptr, 0, length, length); - if ((flags & SWT.DRAW_DELIMITER) != 0 && breaks != null) { - for (int i=0; i<breakCount; i++) { - OS.ATSUSetSoftLineBreak(layout, breaks[i]); - } - } - Font font = data.font; - int atsuiStyle = font.atsuiStyle != 0 ? font.atsuiStyle : data.atsuiStyle; - OS.ATSUSetRunStyle(layout, atsuiStyle, 0, length); - OS.ATSUSetTransientFontMatching(layout, true); - if (data.stringPtr != 0) OS.DisposePtr(data.stringPtr); - data.stringPtr = ptr; - data.string = string; - data.stringLength = length; - data.stringWidth = data.stringHeight = -1; - data.drawFlags = flags; - return length; -} - -/** - * If the argument is <code>true</code>, puts the receiver - * in a drawing mode where the resulting color in the destination - * is the <em>exclusive or</em> of the color values in the source - * and the destination, and if the argument is <code>false</code>, - * puts the receiver in a drawing mode where the destination color - * is replaced with the source color value. - * <p> - * Note that this mode in fundamentally unsupportable on certain - * platforms, notably Carbon (Mac OS X). Clients that want their - * code to run on all platforms need to avoid this method. - * </p> - * - * @param xor if <code>true</code>, then <em>xor</em> mode is used, otherwise <em>source copy</em> mode is used - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @deprecated this functionality is not supported on some platforms - */ -public void setXORMode(boolean xor) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - data.xorMode = xor; - if (OS.VERSION >= 0x1040) { - OS.CGContextSetBlendMode(handle, xor ? OS.kCGBlendModeDifference : OS.kCGBlendModeNormal); - } -} - -/** - * Sets the receiver's text anti-aliasing value to the parameter, - * which must be one of <code>SWT.DEFAULT</code>, <code>SWT.OFF</code> - * or <code>SWT.ON</code>. Note that this controls anti-aliasing only - * for all <em>text drawing</em> operations. - * <p> - * This operation requires the operating system's advanced - * graphics subsystem which may not be available on some - * platforms. - * </p> - * - * @param antialias the anti-aliasing setting - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the parameter is not one of <code>SWT.DEFAULT</code>, - * <code>SWT.OFF</code> or <code>SWT.ON</code></li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> - * </ul> - * - * @see #getAdvanced - * @see #setAdvanced - * @see #setAntialias - * - * @since 3.1 - */ -public void setTextAntialias(int antialias) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - switch (antialias) { - case SWT.DEFAULT: - case SWT.OFF: - case SWT.ON: - break; - default: - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - data.textAntialias = antialias; -} - -/** - * Sets the transform that is currently being used by the receiver. If - * the argument is <code>null</code>, the current transform is set to - * the identity transform. - * <p> - * This operation requires the operating system's advanced - * graphics subsystem which may not be available on some - * platforms. - * </p> - * - * @param transform the transform to set - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the parameter has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> - * </ul> - * - * @see Transform - * @see #getAdvanced - * @see #setAdvanced - * - * @since 3.1 - */ -public void setTransform(Transform transform) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (transform != null && transform.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - if (data.inverseTransform != null) OS.CGContextConcatCTM(handle, data.inverseTransform); - if (transform != null) { - OS.CGContextConcatCTM(handle, transform.handle); - if (data.transform == null) data.transform = new float[6]; - if (data.inverseTransform == null) data.inverseTransform = new float[6]; - System.arraycopy(transform.handle, 0, data.transform, 0, data.transform.length); - System.arraycopy(transform.handle, 0, data.inverseTransform, 0, data.inverseTransform.length); - OS.CGAffineTransformInvert(data.inverseTransform, data.inverseTransform); - } else { - data.transform = data.inverseTransform = null; - } - if (data.forePattern != 0) { - OS.CGPatternRelease(data.forePattern); - data.forePattern = 0; - data.state &= ~(FOREGROUND | FOREGROUND_FILL); - } - if (data.backPattern != 0) { - OS.CGPatternRelease(data.backPattern); - data.backPattern = 0; - data.state &= ~BACKGROUND; - } - data.state &= ~DRAW_OFFSET; -} - -/** - * Returns the extent of the given string. No tab - * expansion or carriage return processing will be performed. - * <p> - * The <em>extent</em> of a string is the width and height of - * the rectangular area it would cover if drawn in a particular - * font (in this case, the current font in the receiver). - * </p> - * - * @param string the string to measure - * @return a point containing the extent of the string - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the string is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public Point stringExtent(String string) { - return textExtent(string, 0); -} - -/** - * Returns the extent of the given string. Tab expansion and - * carriage return processing are performed. - * <p> - * The <em>extent</em> of a string is the width and height of - * the rectangular area it would cover if drawn in a particular - * font (in this case, the current font in the receiver). - * </p> - * - * @param string the string to measure - * @return a point containing the extent of the string - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the string is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public Point textExtent(String string) { - return textExtent(string, SWT.DRAW_DELIMITER | SWT.DRAW_TAB); -} - -/** - * Returns the extent of the given string. Tab expansion, line - * delimiter and mnemonic processing are performed according to - * the specified flags, which can be a combination of: - * <dl> - * <dt><b>DRAW_DELIMITER</b></dt> - * <dd>draw multiple lines</dd> - * <dt><b>DRAW_TAB</b></dt> - * <dd>expand tabs</dd> - * <dt><b>DRAW_MNEMONIC</b></dt> - * <dd>underline the mnemonic character</dd> - * <dt><b>DRAW_TRANSPARENT</b></dt> - * <dd>transparent background</dd> - * </dl> - * <p> - * The <em>extent</em> of a string is the width and height of - * the rectangular area it would cover if drawn in a particular - * font (in this case, the current font in the receiver). - * </p> - * - * @param string the string to measure - * @param flags the flags specifying how to process the text - * @return a point containing the extent of the string - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the string is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public Point textExtent(String string, int flags) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (string == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - checkGC(FONT); - int length = setString(string, flags); - if (data.stringWidth != -1) return new Point(data.stringWidth, data.stringHeight); - int width = 0, height; - if (length == 0) { - height = data.fontAscent + data.fontDescent; - } else { - ATSTrapezoid trapezoid = new ATSTrapezoid(); - if ((flags & SWT.DRAW_DELIMITER) != 0) { - height = 0; - int layout = data.layout; - int[] breakCount = new int[1]; - OS.ATSUGetSoftLineBreaks(layout, 0, length, 0, null, breakCount); - int[] breaks = new int[breakCount[0] + 1]; - OS.ATSUGetSoftLineBreaks(layout, 0, length, breakCount[0], breaks, breakCount); - breaks[breakCount[0]] = length; - for (int i=0, start=0; i<breaks.length; i++) { - int lineBreak = breaks[i]; - OS.ATSUGetGlyphBounds(layout, 0, 0, start, lineBreak - start, (short)OS.kATSUseDeviceOrigins, 1, trapezoid, null); - width = Math.max(width, OS.Fix2Long(trapezoid.lowerRight_x) - OS.Fix2Long(trapezoid.lowerLeft_x)); - height += OS.Fix2Long(trapezoid.lowerRight_y) - OS.Fix2Long(trapezoid.upperRight_y); - start = lineBreak; - } - } else { - OS.ATSUGetGlyphBounds(data.layout, 0, 0, 0, length, (short)OS.kATSUseDeviceOrigins, 1, trapezoid, null); - width = OS.Fix2Long(trapezoid.lowerRight_x) - OS.Fix2Long(trapezoid.lowerLeft_x); - height = OS.Fix2Long(trapezoid.lowerRight_y) - OS.Fix2Long(trapezoid.upperRight_y); - } - } - return new Point(data.stringWidth = width, data.stringHeight = height); -} - -/** - * Returns a string containing a concise, human-readable - * description of the receiver. - * - * @return a string representation of the receiver - */ -public String toString () { - if (isDisposed()) return "GC {*DISPOSED*}"; - return "GC {" + handle + "}"; -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/GCData.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/GCData.java deleted file mode 100644 index 44ea8d6990..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/GCData.java +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2009 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.swt.graphics; - - -import org.eclipse.swt.*; -import org.eclipse.swt.internal.carbon.Rect; - -/** - * Instances of this class are descriptions of GCs in terms - * of unallocated platform-specific data fields. - * <p> - * <b>IMPORTANT:</b> This class is <em>not</em> part of the public - * API for SWT. It is marked public only so that it can be shared - * within the packages provided by SWT. It is not available on all - * platforms, and should never be called from application code. - * </p> - * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> - * @noinstantiate This class is not intended to be instantiated by clients. - */ -public final class GCData { - public Device device; - public int style, state = -1; - public float[] foreground; - public float[] background; - public Pattern foregroundPattern; - public Pattern backgroundPattern; - public Font font; - public int alpha = 0xFF; - public float[] transform; - public float[] inverseTransform; - public float[] clippingTransform; - public int clipRgn; - public float lineWidth; - public int lineStyle = SWT.LINE_SOLID; - public int lineCap = SWT.CAP_FLAT; - public int lineJoin = SWT.JOIN_MITER; - public float lineDashesOffset; - public float[] lineDashes; - public float lineMiterLimit = 10; - public boolean xorMode; - public int antialias = SWT.DEFAULT; - public int textAntialias = SWT.DEFAULT; - public int fillRule = SWT.FILL_EVEN_ODD; - - public float drawXOffset, drawYOffset; - public int forePattern; - public int backPattern; - public Image image; - public int fontAscent; - public int fontDescent; - public int layout; - public int atsuiStyle; - public int tabs; - public String string; - public int stringLength; - public int stringWidth = -1; - public int stringHeight = -1; - public int drawFlags; - public int stringPtr; - public Thread thread; - public int window; - public int paintEvent; - public int visibleRgn; - public int control; - public int port; - public Rect portRect; - public Rect controlRect; - public Rect insetRect; - public boolean updateClip; -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Image.java deleted file mode 100644 index 0bac8c3694..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Image.java +++ /dev/null @@ -1,1013 +0,0 @@ -/******************************************************************************* - * 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.swt.graphics; - - -import org.eclipse.swt.internal.carbon.*; -import org.eclipse.swt.*; -import java.io.*; - -/** - * Instances of this class are graphics which have been prepared - * for display on a specific device. That is, they are ready - * to paint using methods such as <code>GC.drawImage()</code> - * and display on widgets with, for example, <code>Button.setImage()</code>. - * <p> - * If loaded from a file format that supports it, an - * <code>Image</code> may have transparency, meaning that certain - * pixels are specified as being transparent when drawn. Examples - * of file formats that support transparency are GIF and PNG. - * </p><p> - * There are two primary ways to use <code>Images</code>. - * The first is to load a graphic file from disk and create an - * <code>Image</code> from it. This is done using an <code>Image</code> - * constructor, for example: - * <pre> - * Image i = new Image(device, "C:\\graphic.bmp"); - * </pre> - * A graphic file may contain a color table specifying which - * colors the image was intended to possess. In the above example, - * these colors will be mapped to the closest available color in - * SWT. It is possible to get more control over the mapping of - * colors as the image is being created, using code of the form: - * <pre> - * ImageData data = new ImageData("C:\\graphic.bmp"); - * RGB[] rgbs = data.getRGBs(); - * // At this point, rgbs contains specifications of all - * // the colors contained within this image. You may - * // allocate as many of these colors as you wish by - * // using the Color constructor Color(RGB), then - * // create the image: - * Image i = new Image(device, data); - * </pre> - * <p> - * Applications which require even greater control over the image - * loading process should use the support provided in class - * <code>ImageLoader</code>. - * </p><p> - * Application code must explicitly invoke the <code>Image.dispose()</code> - * method to release the operating system resources managed by each instance - * when those instances are no longer required. - * </p> - * - * @see Color - * @see ImageData - * @see ImageLoader - * @see <a href="http://www.eclipse.org/swt/snippets/#image">Image snippets</a> - * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Examples: GraphicsExample, ImageAnalyzer</a> - * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> - */ -public final class Image extends Resource implements Drawable { - - /** - * specifies whether the receiver is a bitmap or an icon - * (one of <code>SWT.BITMAP</code>, <code>SWT.ICON</code>) - * <p> - * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT - * public API. It is marked public only so that it can be shared - * within the packages provided by SWT. It is not available on all - * platforms and should never be accessed from application code. - * </p> - */ - public int type; - - /** - * the handle to the OS image resource - * (Warning: This field is platform dependent) - * <p> - * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT - * public API. It is marked public only so that it can be shared - * within the packages provided by SWT. It is not available on all - * platforms and should never be accessed from application code. - * </p> - */ - public int handle; - - /** - * The data to the OS image resource. - * (Warning: This field is platform dependent) - * <p> - * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT - * public API. It is marked public only so that it can be shared - * within the packages provided by SWT. It is not available on all - * platforms and should never be accessed from application code. - * </p> - */ - public int data; - - /** - * specifies the transparent pixel - */ - int transparentPixel = -1; - - /** - * The GC the image is currently selected in. - */ - GC memGC; - - /** - * The alpha data of the image. - */ - byte[] alphaData; - - /** - * The global alpha value to be used for every pixel. - */ - int alpha = -1; - - /** - * The width of the image. - */ - int width = -1; - - /** - * The height of the image. - */ - int height = -1; - - /** - * Specifies the default scanline padding. - */ - static final int DEFAULT_SCANLINE_PAD = 4; - -Image(Device device) { - super(device); -} - -/** - * Constructs an empty instance of this class with the - * specified width and height. The result may be drawn upon - * by creating a GC and using any of its drawing operations, - * as shown in the following example: - * <pre> - * Image i = new Image(device, width, height); - * GC gc = new GC(i); - * gc.drawRectangle(0, 0, 50, 50); - * gc.dispose(); - * </pre> - * <p> - * Note: Some platforms may have a limitation on the size - * of image that can be created (size depends on width, height, - * and depth). For example, Windows 95, 98, and ME do not allow - * images larger than 16M. - * </p> - * - * @param device the device on which to create the image - * @param width the width of the new image - * @param height the height of the new image - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li> - * <li>ERROR_INVALID_ARGUMENT - if either the width or height is negative or zero</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li> - * </ul> - */ -public Image(Device device, int width, int height) { - super(device); - init(width, height); - init(); -} - -/** - * Constructs a new instance of this class based on the - * provided image, with an appearance that varies depending - * on the value of the flag. The possible flag values are: - * <dl> - * <dt><b>{@link SWT#IMAGE_COPY}</b></dt> - * <dd>the result is an identical copy of srcImage</dd> - * <dt><b>{@link SWT#IMAGE_DISABLE}</b></dt> - * <dd>the result is a copy of srcImage which has a <em>disabled</em> look</dd> - * <dt><b>{@link SWT#IMAGE_GRAY}</b></dt> - * <dd>the result is a copy of srcImage which has a <em>gray scale</em> look</dd> - * </dl> - * - * @param device the device on which to create the image - * @param srcImage the image to use as the source - * @param flag the style, either <code>IMAGE_COPY</code>, <code>IMAGE_DISABLE</code> or <code>IMAGE_GRAY</code> - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li> - * <li>ERROR_NULL_ARGUMENT - if srcImage is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the flag is not one of <code>IMAGE_COPY</code>, <code>IMAGE_DISABLE</code> or <code>IMAGE_GRAY</code></li> - * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_INVALID_IMAGE - if the image is not a bitmap or an icon, or is otherwise in an invalid state</li> - * <li>ERROR_UNSUPPORTED_DEPTH - if the depth of the image is not supported</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li> - * </ul> - */ -public Image(Device device, Image srcImage, int flag) { - super(device); - if (srcImage == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (srcImage.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - switch (flag) { - case SWT.IMAGE_COPY: - case SWT.IMAGE_DISABLE: - case SWT.IMAGE_GRAY: - break; - default: - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - device = this.device; - this.type = srcImage.type; - - /* Get source image size */ - int width = OS.CGImageGetWidth(srcImage.handle); - int height = OS.CGImageGetHeight(srcImage.handle); - int bpr = OS.CGImageGetBytesPerRow(srcImage.handle); - int bpc = OS.CGImageGetBitsPerComponent(srcImage.handle); - int bpp = OS.CGImageGetBitsPerPixel(srcImage.handle); - int colorspace = OS.CGImageGetColorSpace(srcImage.handle); - int alphaInfo = OS.kCGImageAlphaNoneSkipFirst; - - /* Copy transparent pixel and alpha data when necessary */ - alphaInfo = OS.CGImageGetAlphaInfo(srcImage.handle); - transparentPixel = srcImage.transparentPixel; - alpha = srcImage.alpha; - if (srcImage.alphaData != null) { - alphaData = new byte[srcImage.alphaData.length]; - System.arraycopy(srcImage.alphaData, 0, alphaData, 0, alphaData.length); - } - - /* Create the image */ - int dataSize = height * bpr; - data = OS.NewPtr(dataSize); - if (data == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int provider = OS.CGDataProviderCreateWithData(0, data, dataSize, device.releaseProc); - if (provider == 0) { - OS.DisposePtr(data); - SWT.error(SWT.ERROR_NO_HANDLES); - } - handle = OS.CGImageCreate(width, height, bpc, bpp, bpr, colorspace, alphaInfo, provider, null, true, 0); - OS.CGDataProviderRelease(provider); - if (handle == 0) { - OS.DisposePtr(data); - SWT.error(SWT.ERROR_NO_HANDLES); - } - - OS.memmove(data, srcImage.data, dataSize); - if (flag != SWT.IMAGE_COPY) { - - /* Apply transformation */ - switch (flag) { - case SWT.IMAGE_DISABLE: { - Color zeroColor = device.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); - RGB zeroRGB = zeroColor.getRGB(); - byte zeroRed = (byte)zeroRGB.red; - byte zeroGreen = (byte)zeroRGB.green; - byte zeroBlue = (byte)zeroRGB.blue; - Color oneColor = device.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); - RGB oneRGB = oneColor.getRGB(); - byte oneRed = (byte)oneRGB.red; - byte oneGreen = (byte)oneRGB.green; - byte oneBlue = (byte)oneRGB.blue; - byte[] line = new byte[bpr]; - for (int y=0; y<height; y++) { - OS.memmove(line, data + (y * bpr), bpr); - int offset = 0; - for (int x=0; x<width; x++) { - int red = line[offset+1] & 0xFF; - int green = line[offset+2] & 0xFF; - int blue = line[offset+3] & 0xFF; - int intensity = red * red + green * green + blue * blue; - if (intensity < 98304) { - line[offset+1] = zeroRed; - line[offset+2] = zeroGreen; - line[offset+3] = zeroBlue; - } else { - line[offset+1] = oneRed; - line[offset+2] = oneGreen; - line[offset+3] = oneBlue; - } - offset += 4; - } - OS.memmove(data + (y * bpr), line, bpr); - } - break; - } - case SWT.IMAGE_GRAY: { - byte[] line = new byte[bpr]; - for (int y=0; y<height; y++) { - OS.memmove(line, data + (y * bpr), bpr); - int offset = 0; - for (int x=0; x<width; x++) { - int red = line[offset+1] & 0xFF; - int green = line[offset+2] & 0xFF; - int blue = line[offset+3] & 0xFF; - byte intensity = (byte)((red+red+green+green+green+green+green+blue) >> 3); - line[offset+1] = line[offset+2] = line[offset+3] = intensity; - offset += 4; - } - OS.memmove(data + (y * bpr), line, bpr); - } - break; - } - } - } - init(); -} - -/** - * Constructs an empty instance of this class with the - * width and height of the specified rectangle. The result - * may be drawn upon by creating a GC and using any of its - * drawing operations, as shown in the following example: - * <pre> - * Image i = new Image(device, boundsRectangle); - * GC gc = new GC(i); - * gc.drawRectangle(0, 0, 50, 50); - * gc.dispose(); - * </pre> - * <p> - * Note: Some platforms may have a limitation on the size - * of image that can be created (size depends on width, height, - * and depth). For example, Windows 95, 98, and ME do not allow - * images larger than 16M. - * </p> - * - * @param device the device on which to create the image - * @param bounds a rectangle specifying the image's width and height (must not be null) - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li> - * <li>ERROR_NULL_ARGUMENT - if the bounds rectangle is null</li> - * <li>ERROR_INVALID_ARGUMENT - if either the rectangle's width or height is negative</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li> - * </ul> - */ -public Image(Device device, Rectangle bounds) { - super(device); - if (bounds == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - init(bounds.width, bounds.height); - init(); -} - -/** - * Constructs an instance of this class from the given - * <code>ImageData</code>. - * - * @param device the device on which to create the image - * @param data the image data to create the image from (must not be null) - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li> - * <li>ERROR_NULL_ARGUMENT - if the image data is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_UNSUPPORTED_DEPTH - if the depth of the ImageData is not supported</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li> - * </ul> - */ -public Image(Device device, ImageData data) { - super(device); - init(data); - init(); -} - -/** - * Constructs an instance of this class, whose type is - * <code>SWT.ICON</code>, from the two given <code>ImageData</code> - * objects. The two images must be the same size. Pixel transparency - * in either image will be ignored. - * <p> - * The mask image should contain white wherever the icon is to be visible, - * and black wherever the icon is to be transparent. In addition, - * the source image should contain black wherever the icon is to be - * transparent. - * </p> - * - * @param device the device on which to create the icon - * @param source the color data for the icon - * @param mask the mask data for the icon - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li> - * <li>ERROR_NULL_ARGUMENT - if either the source or mask is null </li> - * <li>ERROR_INVALID_ARGUMENT - if source and mask are different sizes</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li> - * </ul> - */ -public Image(Device device, ImageData source, ImageData mask) { - super(device); - if (source == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (mask == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (source.width != mask.width || source.height != mask.height) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - mask = ImageData.convertMask(mask); - ImageData image = new ImageData(source.width, source.height, source.depth, source.palette, source.scanlinePad, source.data); - image.maskPad = mask.scanlinePad; - image.maskData = mask.data; - init(image); - init(); -} - -/** - * Constructs an instance of this class by loading its representation - * from the specified input stream. Throws an error if an error - * occurs while loading the image, or if the result is an image - * of an unsupported type. Application code is still responsible - * for closing the input stream. - * <p> - * This constructor is provided for convenience when loading a single - * image only. If the stream contains multiple images, only the first - * one will be loaded. To load multiple images, use - * <code>ImageLoader.load()</code>. - * </p><p> - * This constructor may be used to load a resource as follows: - * </p> - * <pre> - * static Image loadImage (Display display, Class clazz, String string) { - * InputStream stream = clazz.getResourceAsStream (string); - * if (stream == null) return null; - * Image image = null; - * try { - * image = new Image (display, stream); - * } catch (SWTException ex) { - * } finally { - * try { - * stream.close (); - * } catch (IOException ex) {} - * } - * return image; - * } - * </pre> - * - * @param device the device on which to create the image - * @param stream the input stream to load the image from - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li> - * <li>ERROR_NULL_ARGUMENT - if the stream is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_IO - if an IO error occurs while reading from the stream</li> - * <li>ERROR_INVALID_IMAGE - if the image stream contains invalid data </li> - * <li>ERROR_UNSUPPORTED_DEPTH - if the image stream describes an image with an unsupported depth</li> - * <li>ERROR_UNSUPPORTED_FORMAT - if the image stream contains an unrecognized format</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li> - * </ul> - */ -public Image(Device device, InputStream stream) { - super(device); - init(new ImageData(stream)); - init(); -} - -/** - * Constructs an instance of this class by loading its representation - * from the file with the specified name. Throws an error if an error - * occurs while loading the image, or if the result is an image - * of an unsupported type. - * <p> - * This constructor is provided for convenience when loading - * a single image only. If the specified file contains - * multiple images, only the first one will be used. - * - * @param device the device on which to create the image - * @param filename the name of the file to load the image from - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li> - * <li>ERROR_NULL_ARGUMENT - if the file name is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_IO - if an IO error occurs while reading from the file</li> - * <li>ERROR_INVALID_IMAGE - if the image file contains invalid data </li> - * <li>ERROR_UNSUPPORTED_DEPTH - if the image file describes an image with an unsupported depth</li> - * <li>ERROR_UNSUPPORTED_FORMAT - if the image file contains an unrecognized format</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES if a handle could not be obtained for image creation</li> - * </ul> - */ -public Image(Device device, String filename) { - super(device); - init(new ImageData(filename)); - init(); -} - -void createAlpha () { - if (transparentPixel == -1 && alpha == -1 && alphaData == null) return; - int height = OS.CGImageGetHeight(handle); - int bpr = OS.CGImageGetBytesPerRow(handle); - int dataSize = height * bpr; - byte[] srcData = new byte[dataSize]; - OS.memmove(srcData, data, dataSize); - if (transparentPixel != -1) { - for (int i=0; i<dataSize; i+=4) { - int pixel = ((srcData[i+1] & 0xFF) << 16) | ((srcData[i+2] & 0xFF) << 8) | (srcData[i+3] & 0xFF); - srcData[i] = (byte)(pixel == transparentPixel ? 0 : 0xFF); - } - } else if (alpha != -1) { - byte a = (byte)this.alpha; - for (int i=0; i<dataSize; i+=4) { - srcData[i] = a; - } - } else { - int width = OS.CGImageGetWidth(handle); - int offset = 0, alphaOffset = 0; - for (int y = 0; y<height; y++) { - for (int x = 0; x<width; x++) { - srcData[offset] = alphaData[alphaOffset]; - offset += 4; - alphaOffset += 1; - } - } - } - OS.memmove(data, srcData, dataSize); -} - -void destroy () { - if (memGC != null) memGC.dispose(); - OS.CGImageRelease(handle); - data = handle = 0; - memGC = null; -} - -/** - * Compares the argument to the receiver, and returns true - * if they represent the <em>same</em> object using a class - * specific comparison. - * - * @param object the object to compare with this object - * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise - * - * @see #hashCode - */ -public boolean equals (Object object) { - if (object == this) return true; - if (!(object instanceof Image)) return false; - Image image = (Image)object; - return device == image.device && handle == image.handle && - transparentPixel == image.transparentPixel; -} - -/** - * Returns the color to which to map the transparent pixel, or null if - * the receiver has no transparent pixel. - * <p> - * There are certain uses of Images that do not support transparency - * (for example, setting an image into a button or label). In these cases, - * it may be desired to simulate transparency by using the background - * color of the widget to paint the transparent pixels of the image. - * Use this method to check which color will be used in these cases - * in place of transparency. This value may be set with setBackground(). - * <p> - * - * @return the background color of the image, or null if there is no transparency in the image - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public Color getBackground() { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (transparentPixel == -1) return null; - int red = (transparentPixel >> 16) & 0xFF; - int green = (transparentPixel >> 8) & 0xFF; - int blue = (transparentPixel >> 0) & 0xFF; - return Color.carbon_new(device, new float[]{red / 255f, green / 255f, blue / 255f, 1}); -} - -/** - * Returns the bounds of the receiver. The rectangle will always - * have x and y values of 0, and the width and height of the - * image. - * - * @return a rectangle specifying the image's bounds - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * <li>ERROR_INVALID_IMAGE - if the image is not a bitmap or an icon</li> - * </ul> - */ -public Rectangle getBounds() { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (width != -1 && height != -1) { - return new Rectangle(0, 0, width, height); - } - return new Rectangle(0, 0, width = OS.CGImageGetWidth(handle), height = OS.CGImageGetHeight(handle)); -} - -/** - * Returns an <code>ImageData</code> based on the receiver - * Modifications made to this <code>ImageData</code> will not - * affect the Image. - * - * @return an <code>ImageData</code> containing the image's data and attributes - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * <li>ERROR_INVALID_IMAGE - if the image is not a bitmap or an icon</li> - * </ul> - * - * @see ImageData - */ -public ImageData getImageData() { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - - int width = OS.CGImageGetWidth(handle); - int height = OS.CGImageGetHeight(handle); - int bpr = OS.CGImageGetBytesPerRow(handle); - int bpp = OS.CGImageGetBitsPerPixel(handle); - int dataSize = height * bpr; - byte[] srcData = new byte[dataSize]; - OS.memmove(srcData, data, dataSize); - - PaletteData palette = new PaletteData(0xFF0000, 0xFF00, 0xFF); - ImageData data = new ImageData(width, height, bpp, palette, 4, srcData); - data.bytesPerLine = bpr; - - data.transparentPixel = transparentPixel; - if (transparentPixel == -1 && type == SWT.ICON) { - /* Get the icon mask data */ - int maskPad = 2; - int maskBpl = (((width + 7) / 8) + (maskPad - 1)) / maskPad * maskPad; - byte[] maskData = new byte[height * maskBpl]; - int offset = 0, maskOffset = 0; - for (int y = 0; y<height; y++) { - for (int x = 0; x<width; x++) { - if (srcData[offset] != 0) { - maskData[maskOffset + (x >> 3)] |= (1 << (7 - (x & 0x7))); - } else { - maskData[maskOffset + (x >> 3)] &= ~(1 << (7 - (x & 0x7))); - } - offset += 4; - } - maskOffset += maskBpl; - } - data.maskData = maskData; - data.maskPad = maskPad; - } - for (int i = 0; i < srcData.length; i+= 4) { - srcData[i] = 0; - } - data.alpha = alpha; - if (alpha == -1 && alphaData != null) { - data.alphaData = new byte[alphaData.length]; - System.arraycopy(alphaData, 0, data.alphaData, 0, alphaData.length); - } - return data; -} - -/** - * Invokes platform specific functionality to allocate a new image. - * <p> - * <b>IMPORTANT:</b> This method is <em>not</em> part of the public - * API for <code>Image</code>. It is marked public only so that it - * can be shared within the packages provided by SWT. It is not - * available on all platforms, and should never be called from - * application code. - * </p> - * - * @param device the device on which to allocate the color - * @param type the type of the image (<code>SWT.BITMAP</code> or <code>SWT.ICON</code>) - * @param handle the OS handle for the image - * @param data the OS data for the image - * - * @private - */ -public static Image carbon_new(Device device, int type, int handle, int data) { - Image image = new Image(device); - image.type = type; - image.handle = handle; - image.data = data; - return image; -} - -/** - * Returns an integer hash code for the receiver. Any two - * objects that return <code>true</code> when passed to - * <code>equals</code> must return the same value for this - * method. - * - * @return the receiver's hash - * - * @see #equals - */ -public int hashCode () { - return handle; -} - -void init(int width, int height) { - if (width <= 0 || height <= 0) { - SWT.error (SWT.ERROR_INVALID_ARGUMENT); - } - this.type = SWT.BITMAP; - - /* Create the image */ - int bpr = width * 4; - int dataSize = height * bpr; - data = OS.NewPtr(dataSize); - if (data == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int provider = OS.CGDataProviderCreateWithData(0, data, dataSize, device.releaseProc); - if (provider == 0) { - OS.DisposePtr(data); - SWT.error(SWT.ERROR_NO_HANDLES); - } - int colorspace = device.colorspace; - handle = OS.CGImageCreate(width, height, 8, 32, bpr, colorspace, OS.kCGImageAlphaNoneSkipFirst, provider, null, true, 0); - OS.CGDataProviderRelease(provider); - if (handle == 0) { - OS.DisposePtr(data); - SWT.error(SWT.ERROR_NO_HANDLES); - } - - /* Fill the image with white */ - int bpc = OS.CGImageGetBitsPerComponent(handle); - int context = OS.CGBitmapContextCreate(this.data, width, height, bpc, bpr, colorspace, OS.kCGImageAlphaNoneSkipFirst); - if (context == 0) { - OS.CGImageRelease(handle); - OS.DisposePtr(data); - SWT.error(SWT.ERROR_NO_HANDLES); - } - CGRect rect = new CGRect(); - rect.width = width; rect.height = height; - OS.CGContextSetRGBFillColor(context, 1, 1, 1, 1); - OS.CGContextFillRect(context, rect); - OS.CGContextRelease(context); -} - -void init(ImageData image) { - if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - int width = image.width; - int height = image.height; - PaletteData palette = image.palette; - if (!(((image.depth == 1 || image.depth == 2 || image.depth == 4 || image.depth == 8) && !palette.isDirect) || - ((image.depth == 8) || (image.depth == 16 || image.depth == 24 || image.depth == 32) && palette.isDirect))) - SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); - - - /* Create the image */ - int dataSize = width * height * 4; - data = OS.NewPtr(dataSize); - if (data == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int provider = OS.CGDataProviderCreateWithData(0, data, dataSize, device.releaseProc); - if (provider == 0) { - OS.DisposePtr(data); - SWT.error(SWT.ERROR_NO_HANDLES); - } - int colorspace = device.colorspace; - int transparency = image.getTransparencyType(); - int alphaInfo = transparency == SWT.TRANSPARENCY_NONE && image.alpha == -1 ? OS.kCGImageAlphaNoneSkipFirst : OS.kCGImageAlphaFirst; - handle = OS.CGImageCreate(width, height, 8, 32, width * 4, colorspace, alphaInfo, provider, null, true, 0); - OS.CGDataProviderRelease(provider); - if (handle == 0) { - OS.DisposePtr(data); - SWT.error(SWT.ERROR_NO_HANDLES); - } - - /* Initialize data */ - int bpr = width * 4; - byte[] buffer = new byte[dataSize]; - if (palette.isDirect) { - ImageData.blit(ImageData.BLIT_SRC, - image.data, image.depth, image.bytesPerLine, image.getByteOrder(), 0, 0, width, height, palette.redMask, palette.greenMask, palette.blueMask, - ImageData.ALPHA_OPAQUE, null, 0, 0, 0, - buffer, 32, bpr, ImageData.MSB_FIRST, 0, 0, width, height, 0xFF0000, 0xFF00, 0xFF, - false, false); - } else { - RGB[] rgbs = palette.getRGBs(); - int length = rgbs.length; - byte[] srcReds = new byte[length]; - byte[] srcGreens = new byte[length]; - byte[] srcBlues = new byte[length]; - for (int i = 0; i < rgbs.length; i++) { - RGB rgb = rgbs[i]; - if (rgb == null) continue; - srcReds[i] = (byte)rgb.red; - srcGreens[i] = (byte)rgb.green; - srcBlues[i] = (byte)rgb.blue; - } - ImageData.blit(ImageData.BLIT_SRC, - image.data, image.depth, image.bytesPerLine, image.getByteOrder(), 0, 0, width, height, srcReds, srcGreens, srcBlues, - ImageData.ALPHA_OPAQUE, null, 0, 0, 0, - buffer, 32, bpr, ImageData.MSB_FIRST, 0, 0, width, height, 0xFF0000, 0xFF00, 0xFF, - false, false); - } - - /* Initialize transparency */ - if (transparency == SWT.TRANSPARENCY_MASK || image.transparentPixel != -1) { - this.type = image.transparentPixel != -1 ? SWT.BITMAP : SWT.ICON; - if (image.transparentPixel != -1) { - int transRed = 0, transGreen = 0, transBlue = 0; - if (palette.isDirect) { - RGB rgb = palette.getRGB(image.transparentPixel); - transRed = rgb.red; - transGreen = rgb.green; - transBlue = rgb.blue; - } else { - RGB[] rgbs = palette.getRGBs(); - if (image.transparentPixel < rgbs.length) { - RGB rgb = rgbs[image.transparentPixel]; - transRed = rgb.red; - transGreen = rgb.green; - transBlue = rgb.blue; - } - } - transparentPixel = transRed << 16 | transGreen << 8 | transBlue; - } - ImageData maskImage = image.getTransparencyMask(); - byte[] maskData = maskImage.data; - int maskBpl = maskImage.bytesPerLine; - int offset = 0, maskOffset = 0; - for (int y = 0; y<height; y++) { - for (int x = 0; x<width; x++) { - buffer[offset] = ((maskData[maskOffset + (x >> 3)]) & (1 << (7 - (x & 0x7)))) != 0 ? (byte)0xff : 0; - offset += 4; - } - maskOffset += maskBpl; - } - } else { - this.type = SWT.BITMAP; - if (image.alpha != -1) { - this.alpha = image.alpha; - byte a = (byte)this.alpha; - for (int dataIndex=0; dataIndex<buffer.length; dataIndex+=4) { - buffer[dataIndex] = a; - } - } else if (image.alphaData != null) { - this.alphaData = new byte[image.alphaData.length]; - System.arraycopy(image.alphaData, 0, this.alphaData, 0, alphaData.length); - int offset = 0, alphaOffset = 0; - for (int y = 0; y<height; y++) { - for (int x = 0; x<width; x++) { - buffer[offset] = alphaData[alphaOffset]; - offset += 4; - alphaOffset += 1; - } - } - } - } - - OS.memmove(data, buffer, dataSize); -} - -/** - * Invokes platform specific functionality to allocate a new GC handle. - * <p> - * <b>IMPORTANT:</b> This method is <em>not</em> part of the public - * API for <code>Image</code>. It is marked public only so that it - * can be shared within the packages provided by SWT. It is not - * available on all platforms, and should never be called from - * application code. - * </p> - * - * @param data the platform specific GC data - * @return the platform specific GC handle - */ -public int internal_new_GC (GCData data) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (type != SWT.BITMAP || memGC != null) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - int width = OS.CGImageGetWidth(handle); - int height = OS.CGImageGetHeight(handle); - int bpc = OS.CGImageGetBitsPerComponent(handle); - int bpr = OS.CGImageGetBytesPerRow(handle); - int colorspace = OS.CGImageGetColorSpace(handle); - int context = OS.CGBitmapContextCreate(this.data, width, height, bpc, bpr, colorspace, OS.kCGImageAlphaNoneSkipFirst); - if (context == 0) SWT.error(SWT.ERROR_NO_HANDLES); - OS.CGContextScaleCTM(context, 1, -1); - OS.CGContextTranslateCTM(context, 0, -height); - if (data != null) { - int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT; - if ((data.style & mask) == 0) { - data.style |= SWT.LEFT_TO_RIGHT; - } - data.device = device; - data.background = device.COLOR_WHITE.handle; - data.foreground = device.COLOR_BLACK.handle; - data.font = device.systemFont; - data.image = this; - } - return context; -} - -/** - * Invokes platform specific functionality to dispose a GC handle. - * <p> - * <b>IMPORTANT:</b> This method is <em>not</em> part of the public - * API for <code>Image</code>. It is marked public only so that it - * can be shared within the packages provided by SWT. It is not - * available on all platforms, and should never be called from - * application code. - * </p> - * - * @param hDC the platform specific GC handle - * @param data the platform specific GC data - */ -public void internal_dispose_GC (int context, GCData data) { - OS.CGContextRelease(context); -} - -/** - * Returns <code>true</code> if the image has been disposed, - * and <code>false</code> otherwise. - * <p> - * This method gets the dispose state for the image. - * When an image has been disposed, it is an error to - * invoke any other method using the image. - * - * @return <code>true</code> when the image is disposed and <code>false</code> otherwise - */ -public boolean isDisposed() { - return handle == 0; -} - -/** - * Sets the color to which to map the transparent pixel. - * <p> - * There are certain uses of <code>Images</code> that do not support - * transparency (for example, setting an image into a button or label). - * In these cases, it may be desired to simulate transparency by using - * the background color of the widget to paint the transparent pixels - * of the image. This method specifies the color that will be used in - * these cases. For example: - * <pre> - * Button b = new Button(); - * image.setBackground(b.getBackground()); - * b.setImage(image); - * </pre> - * </p><p> - * The image may be modified by this operation (in effect, the - * transparent regions may be filled with the supplied color). Hence - * this operation is not reversible and it is not legal to call - * this function twice or with a null argument. - * </p><p> - * This method has no effect if the receiver does not have a transparent - * pixel value. - * </p> - * - * @param color the color to use when a transparent pixel is specified - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the color is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the color has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void setBackground(Color color) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (color == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (color.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - if (transparentPixel == -1) return; - byte red = (byte)((transparentPixel >> 16) & 0xFF); - byte green = (byte)((transparentPixel >> 8) & 0xFF); - byte blue = (byte)((transparentPixel >> 0) & 0xFF); - byte newRed = (byte)((int)(color.handle[0] * 255) & 0xFF); - byte newGreen = (byte)((int)(color.handle[1] * 255) & 0xFF); - byte newBlue = (byte)((int)(color.handle[2] * 255) & 0xFF); - int height = OS.CGImageGetHeight(handle); - int bpl = OS.CGImageGetBytesPerRow(handle); - byte[] line = new byte[bpl]; - for (int i = 0, offset = 0; i < height; i++, offset += bpl) { - OS.memmove(line, data + offset, bpl); - for (int j = 0; j < line.length; j += 4) { - if (line[j+ 1] == red && line[j + 2] == green && line[j + 3] == blue) { - line[j + 1] = newRed; - line[j + 2] = newGreen; - line[j + 3] = newBlue; - } - } - OS.memmove(data + offset, line, bpl); - } - transparentPixel = (newRed & 0xFF) << 16 | (newGreen & 0xFF) << 8 | (newBlue & 0xFF); -} - -/** - * Returns a string containing a concise, human-readable - * description of the receiver. - * - * @return a string representation of the receiver - */ -public String toString () { - if (isDisposed()) return "Image {*DISPOSED*}"; - return "Image {" + handle + "}"; -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Path.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Path.java deleted file mode 100644 index a07137b8ca..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Path.java +++ /dev/null @@ -1,813 +0,0 @@ -/******************************************************************************* - * 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.swt.graphics; - -import org.eclipse.swt.*; -import org.eclipse.swt.internal.*; -import org.eclipse.swt.internal.carbon.*; -import org.eclipse.swt.internal.cocoa.*; - -/** - * Instances of this class represent paths through the two-dimensional - * coordinate system. Paths do not have to be continuous, and can be - * described using lines, rectangles, arcs, cubic or quadratic bezier curves, - * glyphs, or other paths. - * <p> - * Application code must explicitly invoke the <code>Path.dispose()</code> - * method to release the operating system resources managed by each instance - * when those instances are no longer required. - * </p> - * <p> - * This class requires the operating system's advanced graphics subsystem - * which may not be available on some platforms. - * </p> - * - * @see <a href="http://www.eclipse.org/swt/snippets/#path">Path, Pattern snippets</a> - * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: GraphicsExample</a> - * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> - * - * @since 3.1 - */ -public class Path extends Resource { - - /** - * the OS resource for the Path - * (Warning: This field is platform dependent) - * <p> - * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT - * public API. It is marked public only so that it can be shared - * within the packages provided by SWT. It is not available on all - * platforms and should never be accessed from application code. - * </p> - */ - public int handle; - - boolean moved, closed = true; - -/** - * Constructs a new empty Path. - * <p> - * This operation requires the operating system's advanced - * graphics subsystem which may not be available on some - * platforms. - * </p> - * - * @param device the device on which to allocate the path - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the device is null and there is no current device</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES if a handle for the path could not be obtained</li> - * </ul> - * - * @see #dispose() - */ -public Path (Device device) { - super(device); - handle = OS.CGPathCreateMutable(); - if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); - init(); -} - -/** - * Constructs a new Path that is a copy of <code>path</code>. If - * <code>flatness</code> is less than or equal to zero, an unflatten - * copy of the path is created. Otherwise, it specifies the maximum - * error between the path and its flatten copy. Smaller numbers give - * better approximation. - * <p> - * This operation requires the operating system's advanced - * graphics subsystem which may not be available on some - * platforms. - * </p> - * - * @param device the device on which to allocate the path - * @param path the path to make a copy - * @param flatness the flatness value - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the device is null and there is no current device</li> - * <li>ERROR_NULL_ARGUMENT - if the path is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the path has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES if a handle for the path could not be obtained</li> - * </ul> - * - * @see #dispose() - * @since 3.4 - */ -public Path (Device device, Path path, float flatness) { - super(device); - if (path == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (path.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - flatness = Math.max(0, flatness); - if (flatness == 0) { - handle = OS.CGPathCreateMutableCopy(path.handle); - if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); - } else { - handle = OS.CGPathCreateMutable(); - if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); - PathData data = path.getPathData(); - int bezierPath = Cocoa.objc_msgSend(Cocoa.C_NSBezierPath, Cocoa.S_bezierPath); - byte[] types = data.types; - float[] points = data.points; - NSPoint point = new NSPoint(), point2 = new NSPoint(), point3 = new NSPoint(); - for (int i = 0, j = 0; i < types.length; i++) { - switch (types[i]) { - case SWT.PATH_MOVE_TO: - point.x = points[j++]; - point.y = points[j++]; - Cocoa.objc_msgSend(bezierPath, Cocoa.S_moveToPoint, point); - break; - case SWT.PATH_LINE_TO: - point.x = points[j++]; - point.y = points[j++]; - Cocoa.objc_msgSend(bezierPath, Cocoa.S_lineToPoint, point); - break; - case SWT.PATH_CUBIC_TO: - point2.x = points[j++]; - point2.y = points[j++]; - point3.x = points[j++]; - point3.y = points[j++]; - point.x = points[j++]; - point.y = points[j++]; - Cocoa.objc_msgSend(bezierPath, Cocoa.S_curveToPoint, point, point2, point3); - break; - case SWT.PATH_QUAD_TO: - float currentX = point.x; - float currentY = point.y; - point2.x = points[j++]; - point2.y = points[j++]; - point.x = points[j++]; - point.y = points[j++]; - float x0 = currentX; - float y0 = currentY; - float cx1 = x0 + 2 * (point2.x - x0) / 3; - float cy1 = y0 + 2 * (point2.y - y0) / 3; - float cx2 = cx1 + (point.x - x0) / 3; - float cy2 = cy1 + (point.y - y0) / 3; - point2.x = cx1; - point2.y = cy1; - point3.x = cx2; - point3.y = cy2; - Cocoa.objc_msgSend(bezierPath, Cocoa.S_curveToPoint, point, point2, point3); - break; - case SWT.PATH_CLOSE: - Cocoa.objc_msgSend(bezierPath, Cocoa.S_closePath); - break; - default: - dispose(); - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - } - Cocoa.objc_msgSend(Cocoa.C_NSBezierPath, Cocoa.S_setDefaultFlatness, flatness); - bezierPath = Cocoa.objc_msgSend(bezierPath, Cocoa.S_bezierPathByFlatteningPath); - int count = Cocoa.objc_msgSend(bezierPath, Cocoa.S_elementCount); - int pointsPtr = OS.malloc(NSPoint.sizeof * 3); - if (pointsPtr == 0) SWT.error(SWT.ERROR_NO_HANDLES); - for (int i = 0; i < count; i++) { - int element = Cocoa.objc_msgSend(bezierPath, Cocoa.S_elementAtIndex_associatedPoints, i, pointsPtr); - switch (element) { - case Cocoa.NSMoveToBezierPathElement: - Cocoa.memmove(point, pointsPtr, NSPoint.sizeof); - moveTo(point.x, point.y); - break; - case Cocoa.NSLineToBezierPathElement: - Cocoa.memmove(point, pointsPtr, NSPoint.sizeof); - lineTo(point.x, point.y); - break; - case Cocoa.NSCurveToBezierPathElement: - Cocoa.memmove(point, pointsPtr, NSPoint.sizeof); - Cocoa.memmove(point2, pointsPtr + NSPoint.sizeof, NSPoint.sizeof); - Cocoa.memmove(point3, pointsPtr + NSPoint.sizeof + NSPoint.sizeof, NSPoint.sizeof); - cubicTo(point2.x, point2.y, point3.x, point3.y, point.x, point.y); - break; - case Cocoa.NSClosePathBezierPathElement: - close(); - break; - } - } - OS.free(pointsPtr); - } - init(); -} - -/** - * Constructs a new Path with the specifed PathData. - * <p> - * This operation requires the operating system's advanced - * graphics subsystem which may not be available on some - * platforms. - * </p> - * - * @param device the device on which to allocate the path - * @param data the data for the path - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the device is null and there is no current device</li> - * <li>ERROR_NULL_ARGUMENT - if the data is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES if a handle for the path could not be obtained</li> - * </ul> - * - * @see #dispose() - * @since 3.4 - */ -public Path (Device device, PathData data) { - this(device); - if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - init(data); -} - -/** - * Adds to the receiver a circular or elliptical arc that lies within - * the specified rectangular area. - * <p> - * The resulting arc begins at <code>startAngle</code> and extends - * for <code>arcAngle</code> degrees. - * Angles are interpreted such that 0 degrees is at the 3 o'clock - * position. A positive value indicates a counter-clockwise rotation - * while a negative value indicates a clockwise rotation. - * </p><p> - * The center of the arc is the center of the rectangle whose origin - * is (<code>x</code>, <code>y</code>) and whose size is specified by the - * <code>width</code> and <code>height</code> arguments. - * </p><p> - * The resulting arc covers an area <code>width + 1</code> pixels wide - * by <code>height + 1</code> pixels tall. - * </p> - * - * @param x the x coordinate of the upper-left corner of the arc - * @param y the y coordinate of the upper-left corner of the arc - * @param width the width of the arc - * @param height the height of the arc - * @param startAngle the beginning angle - * @param arcAngle the angular extent of the arc, relative to the start angle - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void addArc(float x, float y, float width, float height, float startAngle, float arcAngle) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - float[] cmt = new float[6]; - OS.CGAffineTransformMake(width / 2f, 0, 0, height / 2f, x + width / 2f, y + height / 2f, cmt); - float angle = -startAngle * (float)Compatibility.PI / 180; - if (closed) OS.CGPathMoveToPoint(handle, cmt, (float)Math.cos(angle), (float)Math.sin(angle)); - OS.CGPathAddArc(handle, cmt, 0, 0, 1, angle, -(startAngle + arcAngle) * (float)Compatibility.PI / 180, arcAngle >= 0); - moved = true; - closed = false; - if (Math.abs(arcAngle) >= 360) close(); -} - -/** - * Adds to the receiver the path described by the parameter. - * - * @param path the path to add to the receiver - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the parameter is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the parameter has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void addPath(Path path) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (path == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (path.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - OS.CGPathAddPath(handle, null, path.handle); - moved = false; - closed = path.closed; -} - -/** - * Adds to the receiver the rectangle specified by x, y, width and height. - * - * @param x the x coordinate of the rectangle to add - * @param y the y coordinate of the rectangle to add - * @param width the width of the rectangle to add - * @param height the height of the rectangle to add - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void addRectangle(float x, float y, float width, float height) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - CGRect rect = new CGRect(); - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - OS.CGPathAddRect(handle, null, rect); - moved = false; - closed = true; -} - -int newPathProc(int data) { - first = true; - return 0; -} - -int closePathProc(int data) { - first = true; - return 0; -} - -int lineProc(int pt1, int pt2, int data) { - if (first) { - first = false; - OS.memmove(point, pt1, 8); - OS.CGPathMoveToPoint(handle, null, originX + point[0], originY + point[1]); - } - OS.memmove(point, pt2, 8); - OS.CGPathAddLineToPoint(handle, null, originX + point[0], originY + point[1]); - return 0; -} - -int curveProc(int pt1, int controlPt, int pt2, int data) { - if (first) { - first = false; - OS.memmove(point, pt1, 8); - OS.CGPathMoveToPoint(handle, null, originX + point[0], originY + point[1]); - } - OS.memmove(point, pt2, 8); - float x2 = point[0], y2 = point[1]; - OS.memmove(point, controlPt, 8); - OS.CGPathAddQuadCurveToPoint(handle, null, originX + point[0], originY + point[1], originX + x2, originY + y2); - return 0; -} - -float originX, originY; -float[] point = new float[2]; -boolean first; -/** - * Adds to the receiver the pattern of glyphs generated by drawing - * the given string using the given font starting at the point (x, y). - * - * @param string the text to use - * @param x the x coordinate of the starting point - * @param y the y coordinate of the starting point - * @param font the font to use - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the font is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the font has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void addString(String string, float x, float y, Font font) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (font == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (font.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - int length = string.length(); - if (length == 0) return; - moved = false; - closed = true; - - Callback newPathCallback = new Callback(this, "newPathProc", 1); - int newPathProc = newPathCallback.getAddress(); - if (newPathProc == 0) SWT.error(SWT.ERROR_NO_MORE_CALLBACKS); - Callback lineCallback = new Callback(this, "lineProc", 3); - int lineProc = lineCallback.getAddress(); - if (lineProc == 0) SWT.error(SWT.ERROR_NO_MORE_CALLBACKS); - Callback curveCallback = new Callback(this, "curveProc", 4); - int curveProc = curveCallback.getAddress(); - if (curveProc == 0) SWT.error(SWT.ERROR_NO_MORE_CALLBACKS); - Callback closePathCallback = new Callback(this, "closePathProc", 1); - int closePathProc = closePathCallback.getAddress(); - if (closePathProc == 0) SWT.error(SWT.ERROR_NO_MORE_CALLBACKS); - - int style = font.atsuiStyle; - if (style == 0) style = font.createStyle(); - if (style == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int[] buffer = new int[1]; - OS.ATSUCreateTextLayout(buffer); - if (buffer[0] == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int layout = buffer[0]; - char[] chars = new char[length]; - string.getChars(0, length, chars, 0); - int textPtr = OS.NewPtr(length * 2); - if (textPtr == 0) SWT.error(SWT.ERROR_NO_HANDLES); - OS.memmove(textPtr, chars, length * 2); - OS.ATSUSetTextPointerLocation(layout, textPtr, 0, length, length); - OS.ATSUSetRunStyle(layout, style, 0, length); - OS.ATSUSetTransientFontMatching(layout, true); - int[] ascent = new int[1], descent = new int[1]; - OS.ATSUGetUnjustifiedBounds(layout, 0, length, null, null, ascent, descent); - y += OS.Fix2X(ascent[0]); - - int[] layoutRecords = new int[1], numRecords = new int[1], deltaYs = new int[1], numDeltaYs = new int[1]; - OS.ATSUDirectGetLayoutDataArrayPtrFromTextLayout (layout, 0, OS.kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, layoutRecords, numRecords); - OS.ATSUDirectGetLayoutDataArrayPtrFromTextLayout (layout, 0, OS.kATSUDirectDataBaselineDeltaFixedArray, deltaYs, numDeltaYs); - int[] deltaY = new int[1], status = new int[1]; - ATSLayoutRecord record = new ATSLayoutRecord(); - for (int i = 0; i < numRecords[0]; i++) { - OS.memmove(record, layoutRecords[0] + (i * ATSLayoutRecord.sizeof), ATSLayoutRecord.sizeof); - originX = x + (float)OS.Fix2X(record.realPos); - if (deltaYs[0] == 0) { - originY = y; - } else { - OS.memmove(deltaY, deltaYs[0] + (i * 4), 4); - originY = y - (float)OS.Fix2X(deltaY[0]); - } - first = true; - if (record.glyphID != OS.kATSDeletedGlyphcode) { - OS.ATSUGlyphGetQuadraticPaths (style, record.glyphID, newPathProc, lineProc, curveProc, closePathProc, 0, status); - } - } - OS.CGPathCloseSubpath(handle); - if (deltaYs[0] != 0) { - OS.ATSUDirectReleaseLayoutDataArrayPtr(0, OS.kATSUDirectDataBaselineDeltaFixedArray, deltaYs[0]); - } - OS.ATSUDirectReleaseLayoutDataArrayPtr(0, OS.kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, layoutRecords[0]); - - if (style != font.atsuiStyle) OS.ATSUDisposeStyle(style); - if (layout != 0) OS.ATSUDisposeTextLayout(layout); - if (textPtr != 0) OS.DisposePtr(textPtr); - - newPathCallback.dispose(); - lineCallback.dispose(); - curveCallback.dispose(); - closePathCallback.dispose(); -} - -CGPathElement element; -int count, typeCount; -byte[] types; -float[] points; -int applierFunc(int info, int elementPtr) { - OS.memmove(element, elementPtr, CGPathElement.sizeof); - int type = 0, length = 1; - switch (element.type) { - case OS.kCGPathElementMoveToPoint: type = SWT.PATH_MOVE_TO; break; - case OS.kCGPathElementAddLineToPoint: type = SWT.PATH_LINE_TO; break; - case OS.kCGPathElementAddQuadCurveToPoint: type = SWT.PATH_QUAD_TO; length = 2; break; - case OS.kCGPathElementAddCurveToPoint: type = SWT.PATH_CUBIC_TO; length = 3; break; - case OS.kCGPathElementCloseSubpath: type = SWT.PATH_CLOSE; length = 0; break; - } - if (types != null) { - types[typeCount] = (byte)type; - if (length > 0) { - OS.memmove(point, element.points, length * 8); - System.arraycopy(point, 0, points, count, length * 2); - } - } - typeCount++; - count += length * 2; - return 0; -} - -/** - * Closes the current sub path by adding to the receiver a line - * from the current point of the path back to the starting point - * of the sub path. - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void close() { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - OS.CGPathCloseSubpath(handle); - moved = false; - closed = true; -} - -/** - * Returns <code>true</code> if the specified point is contained by - * the receiver and false otherwise. - * <p> - * If outline is <code>true</code>, the point (x, y) checked for containment in - * the receiver's outline. If outline is <code>false</code>, the point is - * checked to see if it is contained within the bounds of the (closed) area - * covered by the receiver. - * - * @param x the x coordinate of the point to test for containment - * @param y the y coordinate of the point to test for containment - * @param gc the GC to use when testing for containment - * @param outline controls whether to check the outline or contained area of the path - * @return <code>true</code> if the path contains the point and <code>false</code> otherwise - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the gc is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the gc has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public boolean contains(float x, float y, GC gc, boolean outline) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (gc == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (gc.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - gc.checkGC(GC.LINE_CAP | GC.LINE_JOIN | GC.LINE_STYLE | GC.LINE_WIDTH); - //TODO - see windows - int pixel = OS.NewPtr(4); - if (pixel == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int[] buffer = new int[]{0xFFFFFFFF}; - OS.memmove(pixel, buffer, 4); - int context = OS.CGBitmapContextCreate(pixel, 1, 1, 8, 4, device.colorspace, OS.kCGImageAlphaNoneSkipFirst); - if (context == 0) { - OS.DisposePtr(pixel); - SWT.error(SWT.ERROR_NO_HANDLES); - } - GCData data = gc.data; - int capStyle = 0; - switch (data.lineCap) { - case SWT.CAP_ROUND: capStyle = OS.kCGLineCapRound; break; - case SWT.CAP_FLAT: capStyle = OS.kCGLineCapButt; break; - case SWT.CAP_SQUARE: capStyle = OS.kCGLineCapSquare; break; - } - OS.CGContextSetLineCap(context, capStyle); - int joinStyle = 0; - switch (data.lineJoin) { - case SWT.JOIN_MITER: joinStyle = OS.kCGLineJoinMiter; break; - case SWT.JOIN_ROUND: joinStyle = OS.kCGLineJoinRound; break; - case SWT.JOIN_BEVEL: joinStyle = OS.kCGLineJoinBevel; break; - } - OS.CGContextSetLineJoin(context, joinStyle); - OS.CGContextSetLineWidth(context, data.lineWidth); - OS.CGContextTranslateCTM(context, -x + 0.5f, -y + 0.5f); - OS.CGContextAddPath(context, handle); - if (outline) { - OS.CGContextStrokePath(context); - } else { - if (data.fillRule == SWT.FILL_WINDING) { - OS.CGContextFillPath(context); - } else { - OS.CGContextEOFillPath(context); - } - } - OS.CGContextRelease(context); - OS.memmove(buffer, pixel, 4); - OS.DisposePtr(pixel); - return buffer[0] != 0xFFFFFFFF; -} - -/** - * Adds to the receiver a cubic bezier curve based on the parameters. - * - * @param cx1 the x coordinate of the first control point of the spline - * @param cy1 the y coordinate of the first control of the spline - * @param cx2 the x coordinate of the second control of the spline - * @param cy2 the y coordinate of the second control of the spline - * @param x the x coordinate of the end point of the spline - * @param y the y coordinate of the end point of the spline - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (!moved) { - CGPoint pt = new CGPoint(); - if (!OS.CGPathIsEmpty(handle)) OS.CGPathGetCurrentPoint(handle, pt); - OS.CGPathMoveToPoint(handle, null, pt.x, pt.y); - moved = true; - } - closed = false; - OS.CGPathAddCurveToPoint(handle, null, cx1, cy1, cx2, cy2, x, y); -} - -void destroy() { - OS.CGPathRelease(handle); - handle = 0; -} - -/** - * Replaces the first four elements in the parameter with values that - * describe the smallest rectangle that will completely contain the - * receiver (i.e. the bounding box). - * - * @param bounds the array to hold the result - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the parameter is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the parameter is too small to hold the bounding box</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void getBounds(float[] bounds) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (bounds == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (bounds.length < 4) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - CGRect rect = new CGRect(); - OS.CGPathGetBoundingBox(handle, rect); - bounds[0] = rect.x; - bounds[1] = rect.y; - bounds[2] = rect.width; - bounds[3] = rect.height; -} - -/** - * Replaces the first two elements in the parameter with values that - * describe the current point of the path. - * - * @param point the array to hold the result - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the parameter is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the parameter is too small to hold the end point</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void getCurrentPoint(float[] point) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (point == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (point.length < 2) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - CGPoint pt = new CGPoint(); - if (!OS.CGPathIsEmpty(handle)) OS.CGPathGetCurrentPoint(handle, pt); - point[0] = pt.x; - point[1] = pt.y; -} - -/** - * Returns a device independent representation of the receiver. - * - * @return the PathData for the receiver - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see PathData - */ -public PathData getPathData() { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - Callback callback = new Callback(this, "applierFunc", 2); - int proc = callback.getAddress(); - if (proc == 0) SWT.error(SWT.ERROR_NO_MORE_CALLBACKS); - count = typeCount = 0; - element = new CGPathElement(); - OS.CGPathApply(handle, 0, proc); - types = new byte[typeCount]; - points = new float[count]; - point = new float[6]; - count = typeCount = 0; - OS.CGPathApply(handle, 0, proc); - callback.dispose(); - PathData result = new PathData(); - result.types = types; - result.points = points; - element = null; - types = null; - points = null; - point = null; - return result; -} - -void init(PathData data) { - byte[] types = data.types; - float[] points = data.points; - for (int i = 0, j = 0; i < types.length; i++) { - switch (types[i]) { - case SWT.PATH_MOVE_TO: - moveTo(points[j++], points[j++]); - break; - case SWT.PATH_LINE_TO: - lineTo(points[j++], points[j++]); - break; - case SWT.PATH_CUBIC_TO: - cubicTo(points[j++], points[j++], points[j++], points[j++], points[j++], points[j++]); - break; - case SWT.PATH_QUAD_TO: - quadTo(points[j++], points[j++], points[j++], points[j++]); - break; - case SWT.PATH_CLOSE: - close(); - break; - default: - dispose(); - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - } -} - -/** - * Returns <code>true</code> if the Path has been disposed, - * and <code>false</code> otherwise. - * <p> - * This method gets the dispose state for the Path. - * When a Path has been disposed, it is an error to - * invoke any other method using the Path. - * - * @return <code>true</code> when the Path is disposed, and <code>false</code> otherwise - */ -public boolean isDisposed() { - return handle == 0; -} - -/** - * Adds to the receiver a line from the current point to - * the point specified by (x, y). - * - * @param x the x coordinate of the end of the line to add - * @param y the y coordinate of the end of the line to add - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void lineTo(float x, float y) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (!moved) { - CGPoint pt = new CGPoint(); - if (!OS.CGPathIsEmpty(handle)) OS.CGPathGetCurrentPoint(handle, pt); - OS.CGPathMoveToPoint(handle, null, pt.x, pt.y); - moved = true; - } - closed = false; - OS.CGPathAddLineToPoint(handle, null, x, y); -} - -/** - * Sets the current point of the receiver to the point - * specified by (x, y). Note that this starts a new - * sub path. - * - * @param x the x coordinate of the new end point - * @param y the y coordinate of the new end point - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void moveTo(float x, float y) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - OS.CGPathMoveToPoint(handle, null, x, y); - /* - * Bug in Quartz. If CGPathMoveToPoint() is not called at the - * begining of a subpath, the following segments do not output - * anything. The fix is to detect that the app did not call - * CGPathMoveToPoint() and call it explicitly. - */ - closed = true; - moved = true; -} - -/** - * Adds to the receiver a quadratic curve based on the parameters. - * - * @param cx the x coordinate of the control point of the spline - * @param cy the y coordinate of the control point of the spline - * @param x the x coordinate of the end point of the spline - * @param y the y coordinate of the end point of the spline - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void quadTo(float cx, float cy, float x, float y) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (!moved) { - CGPoint pt = new CGPoint(); - if (!OS.CGPathIsEmpty(handle)) OS.CGPathGetCurrentPoint(handle, pt); - OS.CGPathMoveToPoint(handle, null, pt.x, pt.y); - moved = true; - } - closed = false; - OS.CGPathAddQuadCurveToPoint(handle, null, cx, cy, x, y); -} - -/** - * Returns a string containing a concise, human-readable - * description of the receiver. - * - * @return a string representation of the receiver - */ -public String toString () { - if (isDisposed()) return "Path {*DISPOSED*}"; - return "Path {" + handle + "}"; -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Pattern.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Pattern.java deleted file mode 100644 index 94fb2fcef7..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Pattern.java +++ /dev/null @@ -1,298 +0,0 @@ -/******************************************************************************* - * 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.swt.graphics; - -import org.eclipse.swt.*; -import org.eclipse.swt.internal.carbon.*; - -/** - * Instances of this class represent patterns to use while drawing. Patterns - * can be specified either as bitmaps or gradients. - * <p> - * Application code must explicitly invoke the <code>Pattern.dispose()</code> - * method to release the operating system resources managed by each instance - * when those instances are no longer required. - * </p> - * <p> - * This class requires the operating system's advanced graphics subsystem - * which may not be available on some platforms. - * </p> - * - * @see <a href="http://www.eclipse.org/swt/snippets/#path">Path, Pattern snippets</a> - * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: GraphicsExample</a> - * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> - * - * @since 3.1 - */ -public class Pattern extends Resource { - int jniRef; - Image image; - float[] color1, color2; - int alpha1, alpha2; - float x1, y1, x2, y2; - int shading; - CGRect drawRect; - -/** - * Constructs a new Pattern given an image. Drawing with the resulting - * pattern will cause the image to be tiled over the resulting area. - * <p> - * This operation requires the operating system's advanced - * graphics subsystem which may not be available on some - * platforms. - * </p> - * - * @param device the device on which to allocate the pattern - * @param image the image that the pattern will draw - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the device is null and there is no current device, or the image is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES if a handle for the pattern could not be obtained</li> - * </ul> - * - * @see #dispose() - */ -public Pattern(Device device, Image image) { - super(device); - if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (image.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - device = this.device; - this.image = image; - device.createPatternCallbacks(); - jniRef = OS.NewGlobalRef(this); - if (jniRef == 0) SWT.error(SWT.ERROR_NO_HANDLES); - init(); -} - -/** - * Constructs a new Pattern that represents a linear, two color - * gradient. Drawing with the pattern will cause the resulting area to be - * tiled with the gradient specified by the arguments. - * <p> - * This operation requires the operating system's advanced - * graphics subsystem which may not be available on some - * platforms. - * </p> - * - * @param device the device on which to allocate the pattern - * @param x1 the x coordinate of the starting corner of the gradient - * @param y1 the y coordinate of the starting corner of the gradient - * @param x2 the x coordinate of the ending corner of the gradient - * @param y2 the y coordinate of the ending corner of the gradient - * @param color1 the starting color of the gradient - * @param color2 the ending color of the gradient - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the device is null and there is no current device, - * or if either color1 or color2 is null</li> - * <li>ERROR_INVALID_ARGUMENT - if either color1 or color2 has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES if a handle for the pattern could not be obtained</li> - * </ul> - * - * @see #dispose() - */ -public Pattern(Device device, float x1, float y1, float x2, float y2, Color color1, Color color2) { - this(device, x1, y1, x2, y2, color1, 0xFF, color2, 0xFF); -} -/** - * Constructs a new Pattern that represents a linear, two color - * gradient. Drawing with the pattern will cause the resulting area to be - * tiled with the gradient specified by the arguments. - * <p> - * This operation requires the operating system's advanced - * graphics subsystem which may not be available on some - * platforms. - * </p> - * - * @param device the device on which to allocate the pattern - * @param x1 the x coordinate of the starting corner of the gradient - * @param y1 the y coordinate of the starting corner of the gradient - * @param x2 the x coordinate of the ending corner of the gradient - * @param y2 the y coordinate of the ending corner of the gradient - * @param color1 the starting color of the gradient - * @param alpha1 the starting alpha value of the gradient - * @param color2 the ending color of the gradient - * @param alpha2 the ending alpha value of the gradient - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the device is null and there is no current device, - * or if either color1 or color2 is null</li> - * <li>ERROR_INVALID_ARGUMENT - if either color1 or color2 has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES if a handle for the pattern could not be obtained</li> - * </ul> - * - * @see #dispose() - * - * @since 3.2 - */ -public Pattern(Device device, float x1, float y1, float x2, float y2, Color color1, int alpha1, Color color2, int alpha2) { - super(device); - if (color1 == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (color1.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - if (color2 == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (color2.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - device = this.device; - this.x1 = x1; - this.y1 = y1; - this.x2 = x2; - this.y2 = y2; - this.color1 = color1.handle; - this.color2 = color2.handle; - this.alpha1 = alpha1; - this.alpha2 = alpha2; - device.createPatternCallbacks(); - jniRef = OS.NewGlobalRef(this); - if (jniRef == 0) SWT.error(SWT.ERROR_NO_HANDLES); - CGPoint start = new CGPoint(); - start.x = x1; - start.y = y1; - CGPoint end = new CGPoint(); - end.x = x2; - end.y = y2; - CGFunctionCallbacks fCallbacks = new CGFunctionCallbacks(); - fCallbacks.evaluate = device.axialShadingProc; - int function = OS.CGFunctionCreate(jniRef, 1, new float[]{0, 1}, 4, new float[]{0, 1, 0, 1, 0, 1, 0, 1}, fCallbacks); - if (function == 0) SWT.error(SWT.ERROR_NO_HANDLES); - shading = OS.CGShadingCreateAxial(device.colorspace, start, end, function, true, true); - OS.CGFunctionRelease(function); - if (shading == 0) SWT.error(SWT.ERROR_NO_HANDLES); - init(); -} - -int axialShadingProc (int ref, int in, int out) { - float[] buffer = new float[4]; - OS.memmove(buffer, in, 4); - float factor2 = buffer[0], factor1 = 1 - factor2; - float[] c1 = color1; - float[] c2 = color2; - float a1 = ((alpha1 & 0xFF) / (float)0xFF); - float a2 = ((alpha2 & 0xFF) / (float)0xFF); - buffer[0] = (c2[0] * factor2) + (c1[0] * factor1); - buffer[1] = (c2[1] * factor2) + (c1[1] * factor1); - buffer[2] = (c2[2] * factor2) + (c1[2] * factor1); - buffer[3] = (a2 * factor2) + (a1 * factor1); - OS.memmove(out, buffer, buffer.length * 4); - return 0; -} - -int createPattern(int context) { - float[] transform = new float[6]; - OS.CGContextGetCTM(context, transform); - CGRect rect = new CGRect(); - if (image != null) { - int imageHandle = image.handle; - rect.width = OS.CGImageGetWidth(imageHandle); - rect.height = OS.CGImageGetHeight(imageHandle); - } else { - rect.x = x1 - 0.5f; - rect.y = y1 - 0.5f; - rect.width = x2 - x1 + 1; - rect.height = y2 - y1 + 1; - } - CGPatternCallbacks callbacks = new CGPatternCallbacks(); - callbacks.drawPattern = device.drawPatternProc; - int pattern = OS.CGPatternCreate(jniRef, rect, transform, rect.width, rect.height, OS.kCGPatternTilingNoDistortion, 0, callbacks); - if (pattern == 0) SWT.error(SWT.ERROR_NO_HANDLES); - return pattern; -} - -void destroy() { - if (jniRef != 0) OS.DeleteGlobalRef(jniRef); - if (shading != 0) OS.CGShadingRelease(shading); - jniRef = shading = 0; - image = null; - color1 = color2 = null; -} - -int drawPatternProc (int ref, int context) { - if (image != null) { - if (image.isDisposed()) return 0; - int imageHandle = image.handle; - int imageWidth = OS.CGImageGetWidth(imageHandle); - int imageHeight = OS.CGImageGetHeight(imageHandle); - CGRect rect = new CGRect(); - rect.width = imageWidth; - rect.height = imageHeight; - OS.CGContextScaleCTM(context, 1, -1); - if (drawRect != null && (drawRect.x % imageWidth) + drawRect.width < imageWidth && (drawRect.y % imageHeight) + drawRect.height < imageHeight) { - rect.x = drawRect.x % imageWidth; - rect.y = drawRect.y % imageHeight; - rect.width = drawRect.width; - rect.height = drawRect.height; - if (OS.VERSION >= 0x1040) { - imageHandle = OS.CGImageCreateWithImageInRect(imageHandle, rect); - } else { - int srcX = (int)drawRect.x, srcY = (int)drawRect.y; - int srcWidth = (int)drawRect.width, srcHeight = (int)drawRect.height; - int bpc = OS.CGImageGetBitsPerComponent(imageHandle); - int bpp = OS.CGImageGetBitsPerPixel(imageHandle); - int bpr = OS.CGImageGetBytesPerRow(imageHandle); - int colorspace = OS.CGImageGetColorSpace(imageHandle); - int alphaInfo = OS.CGImageGetAlphaInfo(imageHandle); - int data = image.data + (srcY * bpr) + srcX * 4; - int provider = OS.CGDataProviderCreateWithData(0, data, srcHeight * bpr, 0); - if (provider != 0) { - imageHandle = OS.CGImageCreate(srcWidth, srcHeight, bpc, bpp, bpr, colorspace, alphaInfo, provider, null, true, 0); - OS.CGDataProviderRelease(provider); - } - } - } - OS.CGContextTranslateCTM(context, 0, -(rect.height + 2 * rect.y)); - OS.CGContextDrawImage(context, rect, imageHandle); - if (imageHandle != 0 && imageHandle != image.handle) OS.CGImageRelease(imageHandle); - } else { - OS.CGContextDrawShading(context, shading); - } - return 0; -} - -/** - * Returns <code>true</code> if the Pattern has been disposed, - * and <code>false</code> otherwise. - * <p> - * This method gets the dispose state for the Pattern. - * When a Pattern has been disposed, it is an error to - * invoke any other method using the Pattern. - * - * @return <code>true</code> when the Pattern is disposed, and <code>false</code> otherwise - */ -public boolean isDisposed() { - return jniRef == 0; -} - -/** - * Returns a string containing a concise, human-readable - * description of the receiver. - * - * @return a string representation of the receiver - */ -public String toString() { - if (isDisposed()) return "Pattern {*DISPOSED*}"; - return "Pattern {" + jniRef + "}"; -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Region.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Region.java deleted file mode 100644 index 033dd07fc7..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Region.java +++ /dev/null @@ -1,597 +0,0 @@ -/******************************************************************************* - * 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.swt.graphics; - - -import org.eclipse.swt.internal.carbon.*; -import org.eclipse.swt.*; - -/** - * Instances of this class represent areas of an x-y coordinate - * system that are aggregates of the areas covered by a number - * of polygons. - * <p> - * Application code must explicitly invoke the <code>Region.dispose()</code> - * method to release the operating system resources managed by each instance - * when those instances are no longer required. - * </p> - * - * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: GraphicsExample</a> - * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> - */ -public final class Region extends Resource { - /** - * the OS resource for the region - * (Warning: This field is platform dependent) - * <p> - * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT - * public API. It is marked public only so that it can be shared - * within the packages provided by SWT. It is not available on all - * platforms and should never be accessed from application code. - * </p> - */ - public int handle; - -/** - * Constructs a new empty region. - * - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES if a handle could not be obtained for region creation</li> - * </ul> - */ -public Region() { - this(null); -} - -/** - * Constructs a new empty region. - * <p> - * You must dispose the region when it is no longer required. - * </p> - * - * @param device the device on which to allocate the region - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES if a handle could not be obtained for region creation</li> - * </ul> - * - * @see #dispose - * - * @since 3.0 - */ -public Region(Device device) { - super(device); - handle = OS.NewRgn(); - if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); - init(); -} - -Region(Device device, int handle) { - super(device); - this.handle = handle; -} - -/** - * Adds the given polygon to the collection of polygons - * the receiver maintains to describe its area. - * - * @param pointArray points that describe the polygon to merge with the receiver - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the argument is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.0 -* - */ -public void add (int[] pointArray) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (pointArray == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (pointArray.length < 2) return; - int polyRgn = OS.NewRgn(); - OS.OpenRgn(); - OS.MoveTo((short)pointArray[0], (short)pointArray[1]); - for (int i = 1; i < pointArray.length / 2; i++) { - OS.LineTo((short)pointArray[2 * i], (short)pointArray[2 * i + 1]); - } - OS.LineTo((short)pointArray[0], (short)pointArray[1]); - OS.CloseRgn(polyRgn); - OS.UnionRgn(handle, polyRgn, handle); - OS.DisposeRgn(polyRgn); -} - -/** - * Adds the given rectangle to the collection of polygons - * the receiver maintains to describe its area. - * - * @param rect the rectangle to merge with the receiver - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the argument is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or height is negative</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void add(Rectangle rect) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (rect == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (rect.width < 0 || rect.height < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - add (rect.x, rect.y, rect.width, rect.height); -} - -/** - * Adds the given rectangle to the collection of polygons - * the receiver maintains to describe its area. - * - * @param x the x coordinate of the rectangle - * @param y the y coordinate of the rectangle - * @param width the width coordinate of the rectangle - * @param height the height coordinate of the rectangle - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or height is negative</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.1 - */ -public void add(int x, int y, int width, int height) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (width < 0 || height < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - int rectRgn = OS.NewRgn(); - Rect r = new Rect(); - OS.SetRect(r, (short)x, (short)y, (short)(x + width),(short)(y + height)); - OS.RectRgn(rectRgn, r); - OS.UnionRgn(handle, rectRgn, handle); - OS.DisposeRgn(rectRgn); -} - -/** - * Adds all of the polygons which make up the area covered - * by the argument to the collection of polygons the receiver - * maintains to describe its area. - * - * @param region the region to merge - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the argument is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void add(Region region) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (region == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (region.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - OS.UnionRgn(handle, region.handle, handle); -} - -/** - * Returns <code>true</code> if the point specified by the - * arguments is inside the area specified by the receiver, - * and <code>false</code> otherwise. - * - * @param x the x coordinate of the point to test for containment - * @param y the y coordinate of the point to test for containment - * @return <code>true</code> if the region contains the point and <code>false</code> otherwise - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public boolean contains(int x, int y) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - org.eclipse.swt.internal.carbon.Point point = new org.eclipse.swt.internal.carbon.Point(); - OS.SetPt(point, (short)x, (short)y); - return OS.PtInRgn(point, handle); -} - -/** - * Returns <code>true</code> if the given point is inside the - * area specified by the receiver, and <code>false</code> - * otherwise. - * - * @param pt the point to test for containment - * @return <code>true</code> if the region contains the point and <code>false</code> otherwise - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the argument is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public boolean contains(Point pt) { - if (pt == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - return contains(pt.x, pt.y); -} - -void destroy() { - OS.DisposeRgn(handle); - handle = 0; -} - -/** - * Compares the argument to the receiver, and returns true - * if they represent the <em>same</em> object using a class - * specific comparison. - * - * @param object the object to compare with this object - * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise - * - * @see #hashCode - */ -public boolean equals(Object object) { - if (this == object) return true; - if (!(object instanceof Region)) return false; - Region region = (Region)object; - return handle == region.handle; -} - -/** - * Returns a rectangle which represents the rectangular - * union of the collection of polygons the receiver - * maintains to describe its area. - * - * @return a bounding rectangle for the region - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see Rectangle#union - */ -public Rectangle getBounds() { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - Rect bounds = new Rect(); - OS.GetRegionBounds(handle, bounds); - int width = bounds.right - bounds.left; - int height = bounds.bottom - bounds.top; - return new Rectangle(bounds.left, bounds.top, width, height); -} - -public static Region carbon_new(Device device, int handle) { - return new Region(device, handle); -} - -/** - * Returns an integer hash code for the receiver. Any two - * objects that return <code>true</code> when passed to - * <code>equals</code> must return the same value for this - * method. - * - * @return the receiver's hash - * - * @see #equals - */ -public int hashCode() { - return handle; -} - -/** - * Intersects the given rectangle to the collection of polygons - * the receiver maintains to describe its area. - * - * @param rect the rectangle to intersect with the receiver - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the argument is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or height is negative</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.0 - */ -public void intersect(Rectangle rect) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (rect == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - intersect (rect.x, rect.y, rect.width, rect.height); -} - -/** - * Intersects the given rectangle to the collection of polygons - * the receiver maintains to describe its area. - * - * @param x the x coordinate of the rectangle - * @param y the y coordinate of the rectangle - * @param width the width coordinate of the rectangle - * @param height the height coordinate of the rectangle - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or height is negative</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.1 - */ -public void intersect(int x, int y, int width, int height) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (width < 0 || height < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - int rectRgn = OS.NewRgn(); - Rect r = new Rect(); - OS.SetRect(r, (short)x, (short)y, (short)(x + width),(short)(y + height)); - OS.RectRgn(rectRgn, r); - OS.SectRgn(handle, rectRgn, handle); - OS.DisposeRgn(rectRgn); -} - -/** - * Intersects all of the polygons which make up the area covered - * by the argument to the collection of polygons the receiver - * maintains to describe its area. - * - * @param region the region to intersect - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the argument is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.0 - */ -public void intersect(Region region) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (region == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (region.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - OS.SectRgn(handle, region.handle, handle); -} - -/** - * Returns <code>true</code> if the rectangle described by the - * arguments intersects with any of the polygons the receiver - * maintains to describe its area, and <code>false</code> otherwise. - * - * @param x the x coordinate of the origin of the rectangle - * @param y the y coordinate of the origin of the rectangle - * @param width the width of the rectangle - * @param height the height of the rectangle - * @return <code>true</code> if the rectangle intersects with the receiver, and <code>false</code> otherwise - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see Rectangle#intersects(Rectangle) - */ -public boolean intersects (int x, int y, int width, int height) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - Rect rect = new Rect(); - OS.SetRect(rect, (short)x, (short)y, (short)(x + width),(short)(y + height)); - return OS.RectInRgn(rect, handle); -} - -/** - * Returns <code>true</code> if the given rectangle intersects - * with any of the polygons the receiver maintains to describe - * its area and <code>false</code> otherwise. - * - * @param rect the rectangle to test for intersection - * @return <code>true</code> if the rectangle intersects with the receiver, and <code>false</code> otherwise - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the argument is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see Rectangle#intersects(Rectangle) - */ -public boolean intersects(Rectangle rect) { - if (rect == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - return intersects(rect.x, rect.y, rect.width, rect.height); -} - -/** - * Returns <code>true</code> if the region has been disposed, - * and <code>false</code> otherwise. - * <p> - * This method gets the dispose state for the region. - * When a region has been disposed, it is an error to - * invoke any other method using the region. - * - * @return <code>true</code> when the region is disposed, and <code>false</code> otherwise - */ -public boolean isDisposed() { - return handle == 0; -} - -/** - * Returns <code>true</code> if the receiver does not cover any - * area in the (x, y) coordinate plane, and <code>false</code> if - * the receiver does cover some area in the plane. - * - * @return <code>true</code> if the receiver is empty, and <code>false</code> otherwise - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public boolean isEmpty() { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - return OS.EmptyRgn(handle); -} - -/** - * Subtracts the given polygon from the collection of polygons - * the receiver maintains to describe its area. - * - * @param pointArray points that describe the polygon to merge with the receiver - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the argument is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.0 - */ -public void subtract (int[] pointArray) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (pointArray == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (pointArray.length < 2) return; - int polyRgn = OS.NewRgn(); - OS.OpenRgn(); - OS.MoveTo((short)pointArray[0], (short)pointArray[1]); - for (int i = 1; i < pointArray.length / 2; i++) { - OS.LineTo((short)pointArray[2 * i], (short)pointArray[2 * i + 1]); - } - OS.LineTo((short)pointArray[0], (short)pointArray[1]); - OS.CloseRgn(polyRgn); - OS.DiffRgn(handle, polyRgn, handle); - OS.DisposeRgn(polyRgn); -} - -/** - * Subtracts the given rectangle from the collection of polygons - * the receiver maintains to describe its area. - * - * @param rect the rectangle to subtract from the receiver - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the argument is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or height is negative</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.0 - */ -public void subtract(Rectangle rect) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (rect == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - subtract (rect.x, rect.y, rect.width, rect.height); -} - -/** - * Subtracts the given rectangle from the collection of polygons - * the receiver maintains to describe its area. - * - * @param x the x coordinate of the rectangle - * @param y the y coordinate of the rectangle - * @param width the width coordinate of the rectangle - * @param height the height coordinate of the rectangle - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the rectangle's width or height is negative</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.1 - */ -public void subtract(int x, int y, int width, int height) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (width < 0 || height < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - int rectRgn = OS.NewRgn(); - Rect r = new Rect(); - OS.SetRect(r, (short)x, (short)y, (short)(x + width),(short)(y + height)); - OS.RectRgn(rectRgn, r); - OS.DiffRgn(handle, rectRgn, handle); - OS.DisposeRgn(rectRgn); -} - -/** - * Subtracts all of the polygons which make up the area covered - * by the argument from the collection of polygons the receiver - * maintains to describe its area. - * - * @param region the region to subtract - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the argument is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the argument has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.0 - */ -public void subtract(Region region) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (region == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (region.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - OS.DiffRgn(handle, region.handle, handle); -} - -/** - * Translate all of the polygons the receiver maintains to describe - * its area by the specified point. - * - * @param x the x coordinate of the point to translate - * @param y the y coordinate of the point to translate - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.1 - */ -public void translate (int x, int y) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - OS.OffsetRgn (handle, (short)x, (short)y); -} - -/** - * Translate all of the polygons the receiver maintains to describe - * its area by the specified point. - * - * @param pt the point to translate - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the argument is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.1 - */ -public void translate (Point pt) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (pt == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - translate (pt.x, pt.y); -} - -/** - * Returns a string containing a concise, human-readable - * description of the receiver. - * - * @return a string representation of the receiver - */ -public String toString () { - if (isDisposed()) return "Region {*DISPOSED*}"; - return "Region {" + handle + "}"; -} -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/TextLayout.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/TextLayout.java deleted file mode 100644 index 9e12f9642b..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/TextLayout.java +++ /dev/null @@ -1,2204 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2009 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.swt.graphics; - -import org.eclipse.swt.internal.*; -import org.eclipse.swt.internal.carbon.*; -import org.eclipse.swt.*; - -/** - * <code>TextLayout</code> is a graphic object that represents - * styled text. - * <p> - * Instances of this class provide support for drawing, cursor - * navigation, hit testing, text wrapping, alignment, tab expansion - * line breaking, etc. These are aspects required for rendering internationalized text. - * </p><p> - * Application code must explicitly invoke the <code>TextLayout#dispose()</code> - * method to release the operating system resources managed by each instance - * when those instances are no longer required. - * </p> - * - * @see <a href="http://www.eclipse.org/swt/snippets/#textlayout">TextLayout, TextStyle snippets</a> - * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: CustomControlExample, StyledText tab</a> - * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> - * - * @since 3.0 - */ -public final class TextLayout extends Resource { - - static class StyleItem { - TextStyle style; - int start; - int atsuStyle; - - void createStyle(Device device, Font defaultFont) { - if (atsuStyle != 0) return; - int[] buffer = new int[1]; - OS.ATSUCreateStyle(buffer); - atsuStyle = buffer[0]; - if (atsuStyle == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int length = 0, ptrLength = 0, index = 0; - Font font = null; - RGBColor foreground = null; - GlyphMetrics metrics = null; - if (style != null) { - font = style.font; - if (style.foreground != null) { - float[] color = style.foreground.handle; - foreground = new RGBColor (); - foreground.red = (short) (color [0] * 0xffff); - foreground.green = (short) (color [1] * 0xffff); - foreground.blue = (short) (color [2] * 0xffff); - } else { - if (style.underline && style.underlineStyle == SWT.UNDERLINE_LINK) { - foreground = new RGBColor (); - foreground.red = (short) 0; - foreground.green = (short) 0x3333; - foreground.blue = (short) 0x9999; - } - } - metrics = style.metrics; - if (isUnderlineSupported(style)) { - length += 1; - ptrLength += 1; - if (style.underlineStyle == SWT.UNDERLINE_DOUBLE) { - length += 1; - ptrLength += 2; - } - if (style.underlineColor != null) { - length += 1; - ptrLength += 4; - } - } - if (style.strikeout) { - length += 1; - ptrLength += 1; - if (style.strikeoutColor != null) { - length += 1; - ptrLength += 4; - } - } - if (metrics != null) { - length += 4; - ptrLength += 28; - } - if (style.rise != 0) { - length += 1; - ptrLength += 4; - } - } - if (font == null) font = defaultFont; - boolean synthesize = false; - if (font != null) { - length += 2; - ptrLength += 8; - synthesize = font.style != 0; - if (synthesize) { - length += 2; - ptrLength += 2; - } - } - if (foreground != null && metrics == null) { - length += 1; - ptrLength += RGBColor.sizeof; - } - byte[] buffer1 = new byte[1]; - int[] tags = new int[length]; - int[] sizes = new int[length]; - int[] values = new int[length]; - int ptr = OS.NewPtr(ptrLength), ptr1 = ptr; - if (font != null) { - buffer[0] = font.handle; - tags[index] = OS.kATSUFontTag; - sizes[index] = 4; - values[index] = ptr1; - OS.memmove(values[index], buffer, sizes[index]); - ptr1 += sizes[index]; - index++; - - buffer[0] = OS.X2Fix(font.size); - tags[index] = OS.kATSUSizeTag; - sizes[index] = 4; - values[index] = ptr1; - OS.memmove(values[index], buffer, sizes[index]); - ptr1 += sizes[index]; - index++; - - if (synthesize) { - buffer1[0] = (font.style & OS.italic) != 0 ? (byte)1 : 0; - tags[index] = OS.kATSUQDItalicTag; - sizes[index] = 1; - values[index] = ptr1; - OS.memmove(values[index], buffer1, sizes[index]); - ptr1 += sizes[index]; - index++; - - buffer1[0] = (font.style & OS.bold) != 0 ? (byte)1 : 0; - tags[index] = OS.kATSUQDBoldfaceTag; - sizes[index] = 1; - values[index] = ptr1; - OS.memmove(values[index], buffer1, sizes[index]); - ptr1 += sizes[index]; - index++; - } - } - int underlineColor = 0, strikeoutColor = 0;; - if (isUnderlineSupported(style)) { - buffer1[0] = (byte)1; - tags[index] = OS.kATSUQDUnderlineTag; - sizes[index] = 1; - values[index] = ptr1; - OS.memmove(values[index], buffer1, sizes[index]); - ptr1 += sizes[index]; - index++; - if (style.underlineStyle == SWT.UNDERLINE_DOUBLE) { - short buffer2[] = {OS.kATSUStyleDoubleLineCount}; - tags[index] = OS.kATSUStyleUnderlineCountOptionTag; - sizes[index] = 2; - values[index] = ptr1; - OS.memmove(values[index], buffer2, sizes[index]); - ptr1 += sizes[index]; - index++; - } - if (style.underlineColor != null) { - buffer[0] = underlineColor = OS.CGColorCreate(device.colorspace, style.underlineColor.handle); - tags[index] = OS.kATSUStyleUnderlineColorOptionTag; - sizes[index] = 4; - values[index] = ptr1; - OS.memmove(values[index], buffer, sizes[index]); - ptr1 += sizes[index]; - index++; - } - } - if (style != null && style.strikeout) { - buffer1[0] = (byte)1; - tags[index] = OS.kATSUStyleStrikeThroughTag; - sizes[index] = 1; - values[index] = ptr1; - OS.memmove(values[index], buffer1, sizes[index]); - ptr1 += sizes[index]; - index++; - if (style.strikeoutColor != null) { - buffer[0] = strikeoutColor = OS.CGColorCreate(device.colorspace, style.strikeoutColor.handle); - tags[index] = OS.kATSUStyleStrikeThroughColorOptionTag; - sizes[index] = 4; - values[index] = ptr1; - OS.memmove(values[index], buffer, sizes[index]); - ptr1 += sizes[index]; - index++; - } - } - if (metrics != null) { - buffer[0] = OS.Long2Fix(metrics.ascent); - tags[index] = OS.kATSUAscentTag; - sizes[index] = 4; - values[index] = ptr1; - OS.memmove(values[index], buffer, sizes[index]); - ptr1 += sizes[index]; - index++; - - buffer[0] = OS.Long2Fix(metrics.descent); - tags[index] = OS.kATSUDescentTag; - sizes[index] = 4; - values[index] = ptr1; - OS.memmove(values[index], buffer, sizes[index]); - ptr1 += sizes[index]; - index++; - - buffer[0] = OS.Long2Fix(metrics.width); - tags[index] = OS.kATSUImposeWidthTag; - sizes[index] = 4; - values[index] = ptr1; - OS.memmove(values[index], buffer, sizes[index]); - ptr1 += sizes[index]; - index++; - - float[] ATSURGBAlphaColor = {0, 0, 0, 0}; - tags[index] = OS.kATSURGBAlphaColorTag; - sizes[index] = 16; - values[index] = ptr1; - OS.memmove(values[index], ATSURGBAlphaColor, sizes[index]); - ptr1 += sizes[index]; - index++; - } - if (style != null && style.rise != 0) { - buffer[0] = OS.Long2Fix(style.rise); - tags[index] = OS.kATSUCrossStreamShiftTag; - sizes[index] = 4; - values[index] = ptr1; - OS.memmove(values[index], buffer, sizes[index]); - ptr1 += sizes[index]; - index++; - } - if (foreground != null && metrics == null) { - tags[index] = OS.kATSUColorTag; - sizes[index] = RGBColor.sizeof; - values[index] = ptr1; - OS.memmove(values[index], foreground, sizes[index]); - ptr1 += sizes[index]; - index++; - } - OS.ATSUSetAttributes(atsuStyle, tags.length, tags, sizes, values); - OS.DisposePtr(ptr); - if (underlineColor != 0) OS.CGColorRelease (underlineColor); - if (strikeoutColor != 0) OS.CGColorRelease (strikeoutColor); - } - - void freeStyle() { - if (atsuStyle == 0) return; - OS.ATSUDisposeStyle(atsuStyle); - atsuStyle = 0; - } - - public String toString () { - return "StyleItem {" + start + ", " + style + "}"; - } - } - - Font font; - String text; - int textPtr; - StyleItem[] styles; - int layout; - int spacing, ascent, descent, indent; - int indentStyle; - int[] tabs; - int[] segments; - int tabsPtr; - int[] breaks, hardBreaks, lineX, lineWidth, lineHeight, lineAscent; - - static final int TAB_COUNT = 32; - int[] invalidOffsets; - static final char LTR_MARK = '\u200E', RTL_MARK = '\u200F', ZWS = '\u200B'; - - static final int UNDERLINE_IME_INPUT = 1 << 16; - static final int UNDERLINE_IME_TARGET_CONVERTED = 2 << 16; - static final int UNDERLINE_IME_CONVERTED = 3 << 16; - -/** - * Constructs a new instance of this class on the given device. - * <p> - * You must dispose the text layout when it is no longer required. - * </p> - * - * @param device the device on which to allocate the text layout - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li> - * </ul> - * - * @see #dispose() - */ -public TextLayout (Device device) { - super(device); - int[] buffer = new int[1]; - OS.ATSUCreateTextLayout(buffer); - if (buffer[0] == 0) SWT.error(SWT.ERROR_NO_HANDLES); - layout = buffer[0]; - setLayoutControl(OS.kATSULineDirectionTag, OS.kATSULeftToRightBaseDirection, 1); - int lineOptions = OS.kATSLineLastNoJustification | OS.kATSLineUseDeviceMetrics | OS.kATSLineKeepSpacesOutOfMargin; - setLayoutControl(OS.kATSULineLayoutOptionsTag, lineOptions, 4); - OS.ATSUSetHighlightingMethod(layout, OS.kRedrawHighlighting, new ATSUUnhighlightData()); - ascent = descent = -1; - text = ""; - styles = new StyleItem[2]; - styles[0] = new StyleItem(); - styles[1] = new StyleItem(); - init(); -} - -void checkLayout() { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); -} - -void computeRuns() { - if (breaks != null) return; - String segmentsText = getSegmentsText(); - int textLength = segmentsText.length(); - char[] chars = new char[textLength + 1]; - segmentsText.getChars(0, textLength, chars, 1); - chars[0] = ZWS; - int breakCount = 1; - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - if (c == '\n' || c == '\r') { - breakCount++; - } - } - hardBreaks = new int [breakCount]; - breakCount = 0; - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - if (c == '\n' || c == '\r') { - chars[i] = ZWS; - hardBreaks[breakCount++] = i; - } - } - if (invalidOffsets != null) { - for (int i = 0; i < invalidOffsets.length; i++) { - invalidOffsets[i]++; - } - } else { - invalidOffsets = new int[0]; - } - - hardBreaks[breakCount] = chars.length; - int newTextPtr = OS.NewPtr(chars.length * 2); - OS.memmove(newTextPtr, chars, chars.length * 2); - OS.ATSUSetTextPointerLocation(layout, newTextPtr, 0, chars.length, chars.length); - OS.ATSUSetTransientFontMatching(layout, true); - if (textPtr != 0) OS.DisposePtr(textPtr); - textPtr = newTextPtr; - - int[] buffer = new int[1]; - Font font = this.font != null ? this.font : device.systemFont; - for (int i = 0; i < styles.length - 1; i++) { - StyleItem run = styles[i]; - run.createStyle(device, font); - //set the default font in the ZWS when text is empty fixes text metrics - int start = textLength != 0 ? translateOffset(run.start) : 0; - int runLength = translateOffset(styles[i + 1].start) - start; - OS.ATSUSetRunStyle(layout, run.atsuStyle, start, runLength); - } - int ptr = OS.NewPtr(12); - buffer = new int[]{OS.Long2Fix(indent), 0, 0}; - OS.memmove(ptr, buffer, 12); - int[] tags = new int[]{OS.kATSUImposeWidthTag, OS.kATSUAscentTag, OS.kATSUDescentTag}; - int[] sizes = new int[]{4, 4, 4}; - int[] values = new int[]{ptr, ptr + 4, ptr + 8}; - OS.ATSUCreateStyle(buffer); - indentStyle = buffer[0]; - OS.ATSUSetAttributes(indentStyle, tags.length, tags, sizes, values); - OS.DisposePtr(ptr); - OS.ATSUSetRunStyle(layout, indentStyle, 0, 1); - for (int i = 0; i < hardBreaks.length-1; i++) { - int offset = hardBreaks[i]; - OS.ATSUSetRunStyle(layout, indentStyle, offset, 1); - } - OS.ATSUGetLayoutControl(layout, OS.kATSULineWidthTag, 4, buffer, null); - int wrapWidth = buffer[0]; - for (int i=0, start=0; i<hardBreaks.length; i++) { - int hardBreak = hardBreaks[i]; - buffer[0] = 0; - if (wrapWidth != 0) OS.ATSUBatchBreakLines(layout, start, hardBreak - start, wrapWidth, buffer); - OS.ATSUSetSoftLineBreak(layout, hardBreak); - start = hardBreak; - } - OS.ATSUGetSoftLineBreaks(layout, 0, OS.kATSUToTextEnd, 0, null, buffer); - int count = buffer[0]; - breaks = new int[count]; - OS.ATSUGetSoftLineBreaks(layout, 0, OS.kATSUToTextEnd, count, breaks, null); - int lineCount = breaks.length; - lineX = new int[lineCount]; - lineWidth = new int[lineCount]; - lineHeight = new int[lineCount]; - lineAscent = new int[lineCount]; - ATSTrapezoid trapezoid = new ATSTrapezoid(); - for (int i=0, start=0; i<lineCount; i++) { - if (ascent != -1) { - ptr = OS.NewPtr(4); - buffer[0] = OS.kATSUseLineHeight; - OS.memmove(ptr, buffer, 4); - tags = new int[]{OS.kATSULineAscentTag}; - sizes = new int[]{4}; - values = new int[]{ptr}; - OS.ATSUSetLineControls(layout, start, tags.length, tags, sizes, values); - OS.ATSUGetLineControl(layout, start, OS.kATSULineAscentTag, 4, buffer, null); - buffer[0] = OS.Long2Fix(Math.max(ascent, OS.Fix2Long(buffer[0]))); - OS.memmove(ptr, buffer, 4); - OS.ATSUSetLineControls(layout, start, tags.length, tags, sizes, values); - OS.DisposePtr(ptr); - } - if (descent != -1) { - ptr = OS.NewPtr(4); - buffer[0] = OS.kATSUseLineHeight; - OS.memmove(ptr, buffer, 4); - tags = new int[]{OS.kATSULineDescentTag}; - sizes = new int[]{4}; - values = new int[]{ptr}; - OS.ATSUSetLineControls(layout, start, tags.length, tags, sizes, values); - OS.ATSUGetLineControl(layout, start, OS.kATSULineDescentTag, 4, buffer, null); - buffer[0] = OS.Long2Fix(Math.max(descent, OS.Fix2Long(buffer[0]))); - OS.memmove(ptr, buffer, 4); - OS.ATSUSetLineControls(layout, start, tags.length, tags, sizes, values); - OS.DisposePtr(ptr); - } - int lineBreak = breaks[i]; - int lineLength = lineBreak - start; - OS.ATSUGetGlyphBounds(layout, 0, 0, start, lineLength, (short)OS.kATSUseDeviceOrigins, 1, trapezoid, null); - lineX[i] = OS.Fix2Long(trapezoid.lowerLeft_x); - lineAscent[i] = -OS.Fix2Long(trapezoid.upperRight_y); - if (lineLength != 0) { - lineWidth[i] = OS.Fix2Long(trapezoid.lowerRight_x) - OS.Fix2Long(trapezoid.lowerLeft_x); - } - lineHeight[i] = OS.Fix2Long(trapezoid.lowerRight_y) + lineAscent[i] + spacing; - start = lineBreak; - } -} - -float[] computePolyline(int left, int top, int right, int bottom) { - int height = bottom - top; // can be any number - int width = 2 * height; // must be even - int peaks = Compatibility.ceil(right - left, width); - if (peaks == 0 && right - left > 2) { - peaks = 1; - } - int length = ((2 * peaks) + 1) * 2; - if (length < 0) return new float[0]; - - float[] coordinates = new float[length]; - for (int i = 0; i < peaks; i++) { - int index = 4 * i; - coordinates[index] = left + (width * i); - coordinates[index+1] = bottom; - coordinates[index+2] = coordinates[index] + width / 2; - coordinates[index+3] = top; - } - coordinates[length-2] = left + (width * peaks); - coordinates[length-1] = bottom; - return coordinates; -} - -void destroy() { - freeRuns(); - font = null; - text = null; - styles = null; - if (layout != 0) OS.ATSUDisposeTextLayout(layout); - layout = 0; - if (textPtr != 0) OS.DisposePtr(textPtr); - textPtr = 0; - if (tabsPtr != 0) OS.DisposePtr(tabsPtr); - tabsPtr = 0; - if (indentStyle != 0) OS.ATSUDisposeStyle(indentStyle); - indentStyle = 0; -} - -/** - * Draws the receiver's text using the specified GC at the specified - * point. - * - * @param gc the GC to draw - * @param x the x coordinate of the top left corner of the rectangular area where the text is to be drawn - * @param y the y coordinate of the top left corner of the rectangular area where the text is to be drawn - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the gc is null</li> - * </ul> - */ -public void draw(GC gc, int x, int y) { - draw(gc, x, y, -1, -1, null, null); -} - -/** - * Draws the receiver's text using the specified GC at the specified - * point. - * - * @param gc the GC to draw - * @param x the x coordinate of the top left corner of the rectangular area where the text is to be drawn - * @param y the y coordinate of the top left corner of the rectangular area where the text is to be drawn - * @param selectionStart the offset where the selections starts, or -1 indicating no selection - * @param selectionEnd the offset where the selections ends, or -1 indicating no selection - * @param selectionForeground selection foreground, or NULL to use the system default color - * @param selectionBackground selection background, or NULL to use the system default color - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the gc is null</li> - * </ul> - */ -public void draw(GC gc, int x, int y, int selectionStart, int selectionEnd, Color selectionForeground, Color selectionBackground) { - draw(gc, x, y, selectionStart, selectionEnd, selectionForeground, selectionBackground, 0); -} - -/** - * Draws the receiver's text using the specified GC at the specified - * point. - * <p> - * The parameter <code>flags</code> can include one of <code>SWT.DELIMITER_SELECTION</code> - * or <code>SWT.FULL_SELECTION</code> to specify the selection behavior on all lines except - * for the last line, and can also include <code>SWT.LAST_LINE_SELECTION</code> to extend - * the specified selection behavior to the last line. - * </p> - * @param gc the GC to draw - * @param x the x coordinate of the top left corner of the rectangular area where the text is to be drawn - * @param y the y coordinate of the top left corner of the rectangular area where the text is to be drawn - * @param selectionStart the offset where the selections starts, or -1 indicating no selection - * @param selectionEnd the offset where the selections ends, or -1 indicating no selection - * @param selectionForeground selection foreground, or NULL to use the system default color - * @param selectionBackground selection background, or NULL to use the system default color - * @param flags drawing options - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the gc is null</li> - * </ul> - * - * @since 3.3 - */ -public void draw(GC gc, int x, int y, int selectionStart, int selectionEnd, Color selectionForeground, Color selectionBackground, int flags) { - checkLayout (); - computeRuns(); - if (gc == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (gc.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - if (selectionForeground != null && selectionForeground.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - if (selectionBackground != null && selectionBackground.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - int length = translateOffset(text.length()); - if (length == 0 && flags == 0) return; - gc.checkGC(GC.FOREGROUND_FILL); - if (gc.data.updateClip) gc.setCGClipping(); - OS.CGContextSaveGState(gc.handle); - setLayoutControl(OS.kATSUCGContextTag, gc.handle, 4); - boolean hasSelection = selectionStart <= selectionEnd && selectionStart != -1 && selectionEnd != -1; - boolean restoreColor = false; - if (hasSelection || (flags & SWT.LAST_LINE_SELECTION) != 0) { - if (selectionBackground != null) { - restoreColor = true; - int color = OS.CGColorCreate(device.colorspace, selectionBackground.handle); - setLayoutControl(OS.kATSULineHighlightCGColorTag, color, 4); - OS.CGColorRelease(color); - } else { - selectionBackground = device.getSystemColor(SWT.COLOR_LIST_BACKGROUND); - } - } - /* - * Feature in ATSU. There is no API to set a background attribute - * of an ATSU style. Draw the background of styles ourselfs. - */ - int rgn = 0; - CGRect rect = null; - for (int j = 0; j < styles.length; j++) { - StyleItem run = styles[j]; - TextStyle style = run.style; - if (style == null || style.background == null) continue; - int start = translateOffset(run.start); - int end = j + 1 < styles.length ? translateOffset(styles[j + 1].start - 1) : length; - for (int i=0, lineStart=0, lineY = 0; i<breaks.length; i++) { - int lineBreak = breaks[i]; - int lineEnd = lineBreak - 1; - if (!(start > lineEnd || end < lineStart)) { - int highStart = Math.max(lineStart, start); - int highEnd = Math.min(lineEnd, end); - int highLen = highEnd - highStart + 1; - if (highLen > 0) { - OS.CGContextSaveGState(gc.handle); - if (rgn == 0) rgn = OS.NewRgn(); - OS.ATSUGetTextHighlight(layout, OS.Long2Fix(x), OS.Long2Fix(y + lineY + lineAscent[i]), highStart, highLen, rgn); - int shape = OS.HIShapeCreateWithQDRgn(rgn); - OS.HIShapeReplacePathInCGContext(shape, gc.handle); - if (rect == null) rect = new CGRect(); - OS.CGContextGetPathBoundingBox(gc.handle, rect); - OS.CGContextEOClip(gc.handle); - OS.CGContextSetFillColorSpace(gc.handle, device.colorspace); - OS.CGContextSetFillColor(gc.handle, style.background.handle); - OS.CGContextFillRect(gc.handle, rect); - OS.DisposeControl(shape); - OS.CGContextRestoreGState(gc.handle); - } - } - if (lineEnd > end) break; - lineY += lineHeight[i]; - lineStart = lineBreak; - } - } - - selectionStart = translateOffset(selectionStart); - selectionEnd = translateOffset(selectionEnd); - OS.CGContextScaleCTM(gc.handle, 1, -1); - int drawX = OS.Long2Fix(x); - int drawY = y; - for (int i=0, start=0; i<breaks.length; i++) { - int lineBreak = breaks[i]; - int lineLength = lineBreak - start; - if (lineLength > 0) { - int fixYDraw = OS.Long2Fix(-(drawY + lineAscent[i])); - OS.ATSUDrawText(layout, start, lineLength, drawX, fixYDraw); - int end = start + lineLength - 1; - if (flags != 0 && (hasSelection || (flags & SWT.LAST_LINE_SELECTION) != 0)) { - boolean extent = false; - if (i == breaks.length - 1 && (flags & SWT.LAST_LINE_SELECTION) != 0) { - extent = true; - } else { - boolean hardBreak = false; - for (int j = 0; j < hardBreaks.length; j++) { - if (end + 1 == hardBreaks[j]) { - hardBreak = true; - break; - } - } - if (hardBreak) { - if (selectionStart <= end + 1 && end + 1 <= selectionEnd) extent = true; - } else { - if (selectionStart <= end + 1 && end + 1 < selectionEnd && (flags & SWT.FULL_SELECTION) != 0) { - extent = true; - } - } - } - if (extent) { - if (rect == null) rect = new CGRect(); - rect.x = x + lineWidth[i]; - rect.y = drawY; - rect.width = (flags & SWT.FULL_SELECTION) != 0 ? 0x7fffffff : lineHeight[i] / 3; - rect.height = lineHeight[i]; - OS.CGContextSaveGState(gc.handle); - OS.CGContextTranslateCTM(gc.handle, 0, -(lineHeight[i] + 2 * drawY)); - OS.CGContextSetFillColorSpace(gc.handle, device.colorspace); - OS.CGContextSetFillColor(gc.handle, selectionBackground.handle); - OS.CGContextFillRect(gc.handle, rect); - OS.CGContextRestoreGState(gc.handle); - } - } - if (hasSelection && !(selectionStart > end || start > selectionEnd)) { - int selStart = Math.max(selectionStart, start); - int selEnd = Math.min(selectionEnd, end); - OS.ATSUHighlightText(layout, drawX, fixYDraw, selStart, selEnd - selStart + 1); - } - } - drawY += lineHeight[i]; - start = lineBreak; - } - if (restoreColor) setLayoutControl(OS.kATSULineHighlightCGColorTag, 0, 4); - OS.CGContextRestoreGState(gc.handle); - - for (int j = 0; j < styles.length; j++) { - StyleItem run = styles[j]; - TextStyle style = run.style; - if (style == null) continue; - boolean drawUnderline = style.underline && !isUnderlineSupported(style); - drawUnderline = drawUnderline && (j + 1 == styles.length || !style.isAdherentUnderline(styles[j + 1].style)); - boolean drawBorder = style.borderStyle != SWT.NONE; - drawBorder = drawBorder && (j + 1 == styles.length || !style.isAdherentBorder(styles[j + 1].style)); - if (!drawUnderline && !drawBorder) continue; - int end = j + 1 < styles.length ? translateOffset(styles[j + 1].start - 1) : length; - for (int i=0, lineStart=0, lineY = 0; i<breaks.length; i++) { - int lineBreak = breaks[i]; - int lineEnd = lineBreak - 1; - if (drawUnderline) { - int start = run.start; - for (int k = j; k > 0 && style.isAdherentUnderline(styles[k - 1].style); k--) { - start = styles[k - 1].start; - } - start = translateOffset(start); - if (!(start > lineEnd || end < lineStart)) { - int highStart = Math.max(lineStart, start); - int highEnd = Math.min(lineEnd, end); - int highLen = highEnd - highStart + 1; - if (highLen > 0) { - OS.CGContextSaveGState(gc.handle); - float underlineY = y + lineY; - float[] foreground = gc.data.foreground; - float lineWidth = 1; - float[] dashes = null; - int lineCap = OS.kCGLineCapButt; - int lineJoin = OS.kCGLineJoinMiter; - switch (style.underlineStyle) { - case SWT.UNDERLINE_ERROR: - lineWidth = 2; - dashes = new float[]{1, 3}; - lineCap = OS.kCGLineCapRound; - lineJoin = OS.kCGLineJoinRound; - //FALLTHROUGH - case SWT.UNDERLINE_SQUIGGLE: - if (style.underlineColor != null) { - foreground = style.underlineColor.handle; - } else { - if (style.foreground != null) { - foreground = style.foreground.handle; - } - } - underlineY += 2 * lineAscent [i] + lineWidth; - break; - case UNDERLINE_IME_INPUT: - case UNDERLINE_IME_TARGET_CONVERTED: - case UNDERLINE_IME_CONVERTED: - lineWidth = 1.5f; - foreground = style.underlineStyle == UNDERLINE_IME_CONVERTED ? new float[]{0.5f, 0.5f, 0.5f, 1} : new float[]{0, 0, 0, 1}; - Font font = style.font; - if (font == null) font = this.font != null ? this.font : device.systemFont; - ATSFontMetrics metrics = new ATSFontMetrics(); - OS.ATSFontGetHorizontalMetrics(font.handle, OS.kATSOptionFlagsDefault, metrics); - underlineY += lineAscent [i] + lineHeight [i] + (metrics.descent * font.size); - break; - } - OS.CGContextSetStrokeColorSpace(gc.handle, device.colorspace); - OS.CGContextSetStrokeColor(gc.handle, foreground); - OS.CGContextSetLineWidth(gc.handle, lineWidth); - OS.CGContextSetLineCap(gc.handle, lineCap); - OS.CGContextSetLineJoin(gc.handle, lineJoin); - OS.CGContextSetLineDash(gc.handle, 0, dashes, dashes != null ? dashes.length : 0); - OS.CGContextTranslateCTM(gc.handle, 0.5f, 0.5f); - - int[] count = new int[1]; - OS.ATSUGetGlyphBounds(layout, OS.Long2Fix(x), OS.X2Fix(underlineY), highStart, highLen, (short)OS.kATSUseDeviceOrigins, 0, 0, count); - int trapezoidsPtr = OS.malloc(count[0] * ATSTrapezoid.sizeof); - OS.ATSUGetGlyphBounds(layout, OS.Long2Fix(x), OS.X2Fix(underlineY), highStart, highLen, (short)OS.kATSUseDeviceOrigins, count[0], trapezoidsPtr, count); - ATSTrapezoid trapezoid = new ATSTrapezoid(); - for (int k = 0; k < count[0]; k++) { - OS.memmove(trapezoid, trapezoidsPtr + (k * ATSTrapezoid.sizeof), ATSTrapezoid.sizeof); - float left, right; - if (trapezoid.upperLeft_x != trapezoid.lowerLeft_x) { - float ux = OS.Fix2Long(trapezoid.upperLeft_x); - float uy = OS.Fix2Long(trapezoid.upperLeft_y); - float lx = OS.Fix2Long(trapezoid.lowerLeft_x); - float ly = OS.Fix2Long(trapezoid.lowerLeft_y); - float a = (uy - ly) / (ux - lx); - float b = uy - ux * a; - left = (underlineY - b) / a; - } else { - left = OS.Fix2Long(trapezoid.upperLeft_x); - } - if (trapezoid.upperRight_x != trapezoid.lowerRight_x) { - float ux = OS.Fix2Long(trapezoid.upperRight_x); - float uy = OS.Fix2Long(trapezoid.upperRight_y); - float lx = OS.Fix2Long(trapezoid.lowerRight_x); - float ly = OS.Fix2Long(trapezoid.lowerRight_y); - float a = (uy - ly) / (ux - lx); - float b = uy - ux * a; - right = (underlineY - b) / a; - } else { - right = OS.Fix2Long(trapezoid.upperRight_x); - } - switch (style.underlineStyle) { - case UNDERLINE_IME_TARGET_CONVERTED: - case UNDERLINE_IME_CONVERTED: - left += 1; - right -= 1; - } - if (style.underlineStyle == SWT.UNDERLINE_SQUIGGLE) { - int lineBottom = y + lineY + lineHeight[i]; - int squigglyThickness = 1; - int squigglyHeight = 2 * squigglyThickness; - float squigglyY = Math.min(OS.Fix2Long(trapezoid.upperLeft_y) - squigglyHeight / 2, lineBottom - squigglyHeight - 1); - float[] points = computePolyline((int)left, (int)squigglyY, (int)right, (int)(squigglyY + squigglyHeight)); - OS.CGContextBeginPath(gc.handle); - OS.CGContextAddLines(gc.handle, points, points.length / 2); - } else { - OS.CGContextMoveToPoint(gc.handle, left, OS.Fix2Long(trapezoid.upperLeft_y)); - OS.CGContextAddLineToPoint(gc.handle, right, OS.Fix2Long(trapezoid.upperRight_y)); - } - } - OS.free(trapezoidsPtr); - OS.CGContextStrokePath(gc.handle); - OS.CGContextRestoreGState(gc.handle); - } - } - } - - if (drawBorder) { - int start = run.start; - for (int k = j; k > 0 && style.isAdherentBorder(styles[k - 1].style); k--) { - start = styles[k - 1].start; - } - start = translateOffset(start); - if (!(start > lineEnd || end < lineStart)) { - int highStart = Math.max(lineStart, start); - int highEnd = Math.min(lineEnd, end); - int highLen = highEnd - highStart + 1; - if (highLen > 0) { - OS.CGContextSaveGState(gc.handle); - int[] count = new int[1]; - OS.ATSUGetGlyphBounds(layout, OS.Long2Fix(x), OS.Long2Fix(y + lineY + lineAscent[i]), highStart, highLen, (short)OS.kATSUseDeviceOrigins, 0, 0, count); - int trapezoidsPtr = OS.malloc(count[0] * ATSTrapezoid.sizeof); - OS.ATSUGetGlyphBounds(layout, OS.Long2Fix(x), OS.Long2Fix(y + lineY + lineAscent[i]), highStart, highLen, (short)OS.kATSUseDeviceOrigins, count[0], trapezoidsPtr, count); - ATSTrapezoid trapezoid = new ATSTrapezoid(); - for (int k = 0; k < count[0]; k++) { - OS.memmove(trapezoid, trapezoidsPtr + (k * ATSTrapezoid.sizeof), ATSTrapezoid.sizeof); - int upperY = y + lineY + 1; - int lowerY = y + lineY + lineHeight[i]; - OS.CGContextMoveToPoint(gc.handle, OS.Fix2Long(trapezoid.lowerLeft_x), lowerY); - OS.CGContextAddLineToPoint(gc.handle, OS.Fix2Long(trapezoid.upperLeft_x), upperY); - OS.CGContextAddLineToPoint(gc.handle, OS.Fix2Long(trapezoid.upperRight_x) - 1, upperY); - OS.CGContextAddLineToPoint(gc.handle, OS.Fix2Long(trapezoid.lowerRight_x) - 1, lowerY); - OS.CGContextClosePath(gc.handle); - } - OS.free(trapezoidsPtr); - int width = 1; - OS.CGContextSetShouldAntialias(gc.handle, false); - OS.CGContextSetLineCap(gc.handle, OS.kCGLineCapButt); - OS.CGContextSetLineJoin(gc.handle, OS.kCGLineJoinMiter); - OS.CGContextSetLineWidth(gc.handle, width); - float[] dashes = null; - switch (style.borderStyle) { - case SWT.BORDER_SOLID: break; - case SWT.BORDER_DASH: dashes = width != 0 ? GC.LINE_DASH : GC.LINE_DASH_ZERO; break; - case SWT.BORDER_DOT: dashes = width != 0 ? GC.LINE_DOT : GC.LINE_DOT_ZERO; break; - } - OS.CGContextSetLineDash(gc.handle, 0, dashes, dashes != null ? dashes.length : 0); - float[] color = null; - if (style.borderColor != null) color = style.borderColor.handle; - if (color == null && style.foreground != null) color = style.foreground.handle; - if (color != null) { - OS.CGContextSetStrokeColorSpace(gc.handle, device.colorspace); - OS.CGContextSetStrokeColor(gc.handle, color); - } - OS.CGContextTranslateCTM (gc.handle, 0.5f, 0.5f); - OS.CGContextStrokePath(gc.handle); - OS.CGContextRestoreGState(gc.handle); - } - } - } - if (lineEnd > end) break; - lineY += lineHeight[i]; - lineStart = lineBreak; - } - } - if (rgn != 0) OS.DisposeRgn(rgn); -} - -void freeRuns() { - if (breaks == null) return; - for (int i = 0; i < styles.length; i++) { - StyleItem run = styles[i]; - run.freeStyle(); - } - if (indentStyle != 0) OS.ATSUDisposeStyle(indentStyle); - indentStyle = 0; - breaks = lineX = lineWidth = lineHeight = lineAscent = null; - invalidOffsets = null; -} - -/** - * Returns the receiver's horizontal text alignment, which will be one - * of <code>SWT.LEFT</code>, <code>SWT.CENTER</code> or - * <code>SWT.RIGHT</code>. - * - * @return the alignment used to positioned text horizontally - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public int getAlignment() { - checkLayout(); - int[] buffer = new int[1]; - OS.ATSUGetLayoutControl(layout, OS.kATSULineFlushFactorTag, 4, buffer, null); - switch (buffer[0]) { - case OS.kATSUCenterAlignment: return SWT.CENTER; - case OS.kATSUEndAlignment: return SWT.RIGHT; - } - return SWT.LEFT; -} - -/** - * Returns the ascent of the receiver. - * - * @return the ascent - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #getDescent() - * @see #setDescent(int) - * @see #setAscent(int) - * @see #getLineMetrics(int) - */ -public int getAscent () { - checkLayout(); - return ascent; -} - -/** - * Returns the bounds of the receiver. The width returned is either the - * width of the longest line or the width set using {@link TextLayout#setWidth(int)}. - * To obtain the text bounds of a line use {@link TextLayout#getLineBounds(int)}. - * - * @return the bounds of the receiver - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #setWidth(int) - * @see #getLineBounds(int) - */ -public Rectangle getBounds() { - checkLayout(); - computeRuns(); - int width = 0, height = 0; - int length = text.length(); - if (length == 0) { - Font font = this.font != null ? this.font : device.systemFont; - ATSFontMetrics metrics = new ATSFontMetrics(); - OS.ATSFontGetVerticalMetrics(font.handle, OS.kATSOptionFlagsDefault, metrics); - OS.ATSFontGetHorizontalMetrics(font.handle, OS.kATSOptionFlagsDefault, metrics); - int ascent = (int)(0.5f + metrics.ascent * font.size); - int descent = (int)(0.5f + (-metrics.descent + metrics.leading) * font.size); - ascent = Math.max(ascent, this.ascent); - descent = Math.max(descent, this.descent); - height = ascent + descent; - } else { - for (int i=0; i<breaks.length; i++) { - width = Math.max(width, lineWidth[i]); - height += lineHeight[i]; - } - } - int[] buffer = new int[1]; - OS.ATSUGetLayoutControl(layout, OS.kATSULineWidthTag, 4, buffer, null); - int wrapWidth = OS.Fix2Long(buffer[0]); - if (wrapWidth != 0) width = Math.max(width, wrapWidth); - return new Rectangle(0, 0, width, height); -} - -/** - * Returns the bounds for the specified range of characters. The - * bounds is the smallest rectangle that encompasses all characters - * in the range. The start and end offsets are inclusive and will be - * clamped if out of range. - * - * @param start the start offset - * @param end the end offset - * @return the bounds of the character range - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public Rectangle getBounds(int start, int end) { - checkLayout(); - computeRuns(); - int length = text.length(); - if (length == 0) return new Rectangle(0, 0, 0, 0); - if (start > end) return new Rectangle(0, 0, 0, 0); - start = Math.min(Math.max(0, start), length - 1); - end = Math.min(Math.max(0, end), length - 1); - start = translateOffset(start); - end = translateOffset(end); - for (int i = 0; i < hardBreaks.length; i++) { - if (start == hardBreaks[i]) { - if (start > 0) start--; - } - if (end == hardBreaks[i]) { - if (end > 0) end--; - } - } - int rgn = OS.NewRgn(); - Rect rect = new Rect(); - Rect rect1 = new Rect(); - for (int i=0, lineStart=0, lineY = 0; i<breaks.length; i++) { - int lineBreak = breaks[i]; - int lineEnd = lineBreak - 1; - if (!(start > lineEnd || end < lineStart)) { - int highStart = Math.max(lineStart, start); - int highEnd = Math.min(lineEnd, end); - int highLen = highEnd - highStart + 1; - if (highLen > 0) { - OS.ATSUGetTextHighlight(layout, 0, OS.Long2Fix(lineY + lineAscent[i]), highStart, highLen, rgn); - OS.GetRegionBounds(rgn, rect1); - OS.UnionRect(rect, rect1, rect); - } - } - if (lineEnd > end) break; - lineY += lineHeight[i]; - lineStart = lineBreak; - } - OS.DisposeRgn(rgn); - return new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); -} - -/** - * Returns the descent of the receiver. - * - * @return the descent - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #getAscent() - * @see #setAscent(int) - * @see #setDescent(int) - * @see #getLineMetrics(int) - */ -public int getDescent () { - checkLayout(); - return descent; -} - -/** - * Returns the default font currently being used by the receiver - * to draw and measure text. - * - * @return the receiver's font - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public Font getFont () { - checkLayout(); - return font; -} - -/** -* Returns the receiver's indent. -* -* @return the receiver's indent -* -* @exception SWTException <ul> -* <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> -* </ul> -* -* @since 3.2 -*/ -public int getIndent () { - checkLayout(); - return indent; -} - -/** -* Returns the receiver's justification. -* -* @return the receiver's justification -* -* @exception SWTException <ul> -* <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> -* </ul> -* -* @since 3.2 -*/ -public boolean getJustify () { - checkLayout(); - int[] buffer = new int[1]; - OS.ATSUGetLayoutControl(layout, OS.kATSULineJustificationFactorTag, 4, buffer, null); - return buffer[0] == OS.kATSUFullJustification; -} - -/** - * Returns the embedding level for the specified character offset. The - * embedding level is usually used to determine the directionality of a - * character in bidirectional text. - * - * @param offset the character offset - * @return the embedding level - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the character offset is out of range</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - */ -public int getLevel(int offset) { - checkLayout(); - computeRuns(); - int length = text.length(); - if (!(0 <= offset && offset <= length)) SWT.error(SWT.ERROR_INVALID_RANGE); - offset = translateOffset(offset); - int level = 0; - //TODO - return level; -} - -/** - * Returns the line offsets. Each value in the array is the - * offset for the first character in a line except for the last - * value, which contains the length of the text. - * - * @return the line offsets - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public int[] getLineOffsets() { - checkLayout (); - computeRuns(); - int[] offsets = new int[breaks.length + 1]; - for (int i = 1; i < offsets.length; i++) { - offsets[i] = untranslateOffset(breaks[i - 1]); - } - return offsets; -} - -/** - * Returns the index of the line that contains the specified - * character offset. - * - * @param offset the character offset - * @return the line index - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the character offset is out of range</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public int getLineIndex(int offset) { - checkLayout (); - computeRuns(); - int length = text.length(); - if (!(0 <= offset && offset <= length)) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - offset = translateOffset(offset); - for (int i=0; i<breaks.length-1; i++) { - int lineBreak = breaks[i]; - if (lineBreak > offset) return i; - } - return breaks.length - 1; -} - -/** - * Returns the bounds of the line for the specified line index. - * - * @param lineIndex the line index - * @return the line bounds - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the line index is out of range</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public Rectangle getLineBounds(int lineIndex) { - checkLayout(); - computeRuns(); - int lineCount = breaks.length; - if (!(0 <= lineIndex && lineIndex < lineCount)) SWT.error(SWT.ERROR_INVALID_RANGE); - int lineY = 0; - for (int i=0; i<lineIndex; i++) { - lineY += lineHeight[i]; - } - int lineX = this.lineX[lineIndex]; - int lineWidth = this.lineWidth[lineIndex]; - int lineHeight = this.lineHeight[lineIndex] - spacing; - return new Rectangle(lineX, lineY, lineWidth, lineHeight); -} - -/** - * Returns the receiver's line count. This includes lines caused - * by wrapping. - * - * @return the line count - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public int getLineCount() { - checkLayout (); - computeRuns(); - return breaks.length; -} - -/** - * Returns the font metrics for the specified line index. - * - * @param lineIndex the line index - * @return the font metrics - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the line index is out of range</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public FontMetrics getLineMetrics (int lineIndex) { - checkLayout (); - computeRuns(); - int lineCount = breaks.length; - if (!(0 <= lineIndex && lineIndex < lineCount)) SWT.error(SWT.ERROR_INVALID_RANGE); - int length = text.length(); - if (length == 0) { - Font font = this.font != null ? this.font : device.systemFont; - ATSFontMetrics metrics = new ATSFontMetrics(); - OS.ATSFontGetVerticalMetrics(font.handle, OS.kATSOptionFlagsDefault, metrics); - OS.ATSFontGetHorizontalMetrics(font.handle, OS.kATSOptionFlagsDefault, metrics); - int ascent = (int)(0.5f + metrics.ascent * font.size); - int descent = (int)(0.5f + (-metrics.descent + metrics.leading) * font.size); - ascent = Math.max(ascent, this.ascent); - descent = Math.max(descent, this.descent); - return FontMetrics.carbon_new(ascent, descent, 0, 0, ascent + descent); - } - int start = lineIndex == 0 ? 0 : breaks[lineIndex - 1]; - int lineLength = breaks[lineIndex] - start; - int[] ascent = new int[1], descent = new int[1]; - OS.ATSUGetUnjustifiedBounds(layout, start, lineLength, null, null, ascent, descent); - int height = OS.Fix2Long(ascent[0]) + OS.Fix2Long(descent[0]); - return FontMetrics.carbon_new(OS.Fix2Long(ascent[0]), OS.Fix2Long(descent[0]), 0, 0, height); -} - -/** - * Returns the location for the specified character offset. The - * <code>trailing</code> argument indicates whether the offset - * corresponds to the leading or trailing edge of the cluster. - * - * @param offset the character offset - * @param trailing the trailing flag - * @return the location of the character offset - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #getOffset(Point, int[]) - * @see #getOffset(int, int, int[]) - */ -public Point getLocation(int offset, boolean trailing) { - checkLayout(); - computeRuns(); - int length = text.length(); - if (!(0 <= offset && offset <= length)) SWT.error(SWT.ERROR_INVALID_RANGE); - if (length == 0) return new Point(0, 0); - offset = translateOffset(offset); - for (int i = 0; i < hardBreaks.length; i++) { - if (offset == hardBreaks[i]) { - trailing = true; - if (offset > 0) offset--; - break; - } - } - int lineY = 0; - for (int i=0; i<breaks.length-1; i++) { - int lineBreak = breaks[i]; - if (lineBreak > offset) break; - lineY += lineHeight[i]; - } - if (trailing) offset++; - ATSUCaret caret = new ATSUCaret(); - OS.ATSUOffsetToPosition(layout, offset, !trailing, caret, null, null); - return new Point(Math.min(OS.Fix2Long(caret.fX), OS.Fix2Long(caret.fDeltaX)), lineY); -} - -/** - * Returns the next offset for the specified offset and movement - * type. The movement is one of <code>SWT.MOVEMENT_CHAR</code>, - * <code>SWT.MOVEMENT_CLUSTER</code>, <code>SWT.MOVEMENT_WORD</code>, - * <code>SWT.MOVEMENT_WORD_END</code> or <code>SWT.MOVEMENT_WORD_START</code>. - * - * @param offset the start offset - * @param movement the movement type - * @return the next offset - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the offset is out of range</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #getPreviousOffset(int, int) - */ -public int getNextOffset (int offset, int movement) { - return _getOffset(offset, movement, true); -} - -int _getOffset (int offset, int movement, boolean forward) { - checkLayout(); - computeRuns(); - int length = text.length(); - if (!(0 <= offset && offset <= length)) SWT.error(SWT.ERROR_INVALID_RANGE); - if (length == 0) return 0; - offset = translateOffset(offset); - int newOffset; - int type = OS.kATSUByCharacter; - switch (movement) { - case SWT.MOVEMENT_CLUSTER: type = OS.kATSUByCharacterCluster; break; - case SWT.MOVEMENT_WORD: type = OS.kATSUByWord; break; - } - if (forward) { - offset = _getNativeOffset(offset, type, forward); - newOffset = untranslateOffset(offset); - if (movement == SWT.MOVEMENT_WORD || movement == SWT.MOVEMENT_WORD_END) { - while (newOffset < length && - (!(!Compatibility.isLetterOrDigit(text.charAt(newOffset)) && - Compatibility.isLetterOrDigit(text.charAt(newOffset - 1))))) { - offset = _getNativeOffset(offset, type, forward); - newOffset = untranslateOffset(offset); - } - } - if (movement == SWT.MOVEMENT_WORD_START) { - while (newOffset < length && - (!(Compatibility.isLetterOrDigit(text.charAt(newOffset)) && - !Compatibility.isLetterOrDigit(text.charAt(newOffset - 1))))) { - offset = _getNativeOffset(offset, type, forward); - newOffset = untranslateOffset(offset); - } - } - } else { - offset = _getNativeOffset(offset, type, forward); - newOffset = untranslateOffset(offset); - if (movement == SWT.MOVEMENT_WORD || movement == SWT.MOVEMENT_WORD_START) { - while (newOffset > 0 && - (!(Compatibility.isLetterOrDigit(text.charAt(newOffset)) && - !Compatibility.isLetterOrDigit(text.charAt(newOffset - 1))))) { - offset = _getNativeOffset(offset, type, forward); - newOffset = untranslateOffset(offset); - } - } - if (movement == SWT.MOVEMENT_WORD_END) { - while (newOffset > 0 && - (!(!Compatibility.isLetterOrDigit(text.charAt(newOffset)) && - Compatibility.isLetterOrDigit(text.charAt(newOffset - 1))))) { - offset = _getNativeOffset(offset, type, forward); - newOffset = untranslateOffset(offset); - } - } - } - return newOffset; -} - -int _getNativeOffset(int offset, int movement, boolean forward) { - int[] buffer = new int [1]; - boolean invalid = false; - do { - if (forward) { - OS.ATSUNextCursorPosition(layout, offset, movement, buffer); - } else { - OS.ATSUPreviousCursorPosition(layout, offset, movement, buffer); - } - if (buffer[0] == offset) return offset; - offset = buffer[0]; - invalid = false; - for (int i = 0; i < invalidOffsets.length; i++) { - if (offset == invalidOffsets[i]) { - invalid = true; - break; - } - } - } while (invalid); - return offset; -} - -/** - * Returns the character offset for the specified point. - * For a typical character, the trailing argument will be filled in to - * indicate whether the point is closer to the leading edge (0) or - * the trailing edge (1). When the point is over a cluster composed - * of multiple characters, the trailing argument will be filled with the - * position of the character in the cluster that is closest to - * the point. - * - * @param point the point - * @param trailing the trailing buffer - * @return the character offset - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the trailing length is less than <code>1</code></li> - * <li>ERROR_NULL_ARGUMENT - if the point is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #getLocation(int, boolean) - */ -public int getOffset(Point point, int[] trailing) { - checkLayout(); - computeRuns(); - if (point == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - return getOffset(point.x, point.y, trailing); -} - -/** - * Returns the character offset for the specified point. - * For a typical character, the trailing argument will be filled in to - * indicate whether the point is closer to the leading edge (0) or - * the trailing edge (1). When the point is over a cluster composed - * of multiple characters, the trailing argument will be filled with the - * position of the character in the cluster that is closest to - * the point. - * - * @param x the x coordinate of the point - * @param y the y coordinate of the point - * @param trailing the trailing buffer - * @return the character offset - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the trailing length is less than <code>1</code></li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #getLocation(int, boolean) - */ -public int getOffset(int x, int y, int[] trailing) { - checkLayout(); - computeRuns(); - if (trailing != null && trailing.length < 1) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - int length = text.length(); - if (length == 0) return 0; - int lineY = 0, start = 0, lineIndex; - for (lineIndex=0; lineIndex<breaks.length-1; lineIndex++) { - int lineBreak = breaks[lineIndex]; - int height = lineHeight[lineIndex]; - if (lineY + height > y) break; - lineY += height; - start = lineBreak; - } - int[] offset = new int[]{start}; - boolean[] leading = new boolean[1]; - OS.ATSUPositionToOffset(layout, OS.Long2Fix(x), OS.Long2Fix(y - lineY), offset, leading, null); - if (trailing != null) trailing[0] = (leading[0] ? 0 : 1); - if (!leading[0]) offset[0]--; - for (int i = 0; i < hardBreaks.length; i++) { - if (offset[0] == hardBreaks[i]) { - offset[0]++; - break; - } - } - offset[0] = untranslateOffset(offset[0]); - if (offset[0] > length - 1) { - offset[0] = length - 1; - if (trailing != null) trailing[0] = 1; - } - return offset[0]; -} - -/** - * Returns the orientation of the receiver. - * - * @return the orientation style - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public int getOrientation() { - checkLayout(); - int[] lineDir = new int[1]; - OS.ATSUGetLayoutControl(layout, OS.kATSULineDirectionTag, 1, lineDir, null); - return lineDir[0] == OS.kATSURightToLeftBaseDirection ? SWT.RIGHT_TO_LEFT : SWT.LEFT_TO_RIGHT; -} - -/** - * Returns the previous offset for the specified offset and movement - * type. The movement is one of <code>SWT.MOVEMENT_CHAR</code>, - * <code>SWT.MOVEMENT_CLUSTER</code> or <code>SWT.MOVEMENT_WORD</code>, - * <code>SWT.MOVEMENT_WORD_END</code> or <code>SWT.MOVEMENT_WORD_START</code>. - * - * @param offset the start offset - * @param movement the movement type - * @return the previous offset - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the offset is out of range</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #getNextOffset(int, int) - */ -public int getPreviousOffset (int index, int movement) { - return _getOffset(index, movement, false); -} - -/** - * Gets the ranges of text that are associated with a <code>TextStyle</code>. - * - * @return the ranges, an array of offsets representing the start and end of each - * text style. - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #getStyles() - * - * @since 3.2 - */ -public int[] getRanges () { - checkLayout(); - int[] result = new int[styles.length * 2]; - int count = 0; - for (int i=0; i<styles.length - 1; i++) { - if (styles[i].style != null) { - result[count++] = styles[i].start; - result[count++] = styles[i + 1].start - 1; - } - } - if (count != result.length) { - int[] newResult = new int[count]; - System.arraycopy(result, 0, newResult, 0, count); - result = newResult; - } - return result; -} - -/** - * Returns the text segments offsets of the receiver. - * - * @return the text segments offsets - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public int[] getSegments() { - checkLayout(); - return segments; -} - -String getSegmentsText() { - if (segments == null) return text; - int nSegments = segments.length; - if (nSegments <= 1) return text; - int length = text.length(); - if (length == 0) return text; - if (nSegments == 2) { - if (segments[0] == 0 && segments[1] == length) return text; - } - invalidOffsets = new int[nSegments]; - char[] oldChars = new char[length]; - text.getChars(0, length, oldChars, 0); - char[] newChars = new char[length + nSegments]; - int charCount = 0, segmentCount = 0; - char separator = getOrientation() == SWT.RIGHT_TO_LEFT ? RTL_MARK : LTR_MARK; - while (charCount < length) { - if (segmentCount < nSegments && charCount == segments[segmentCount]) { - invalidOffsets[segmentCount] = charCount + segmentCount; - newChars[charCount + segmentCount++] = separator; - } else { - newChars[charCount + segmentCount] = oldChars[charCount++]; - } - } - if (segmentCount < nSegments) { - invalidOffsets[segmentCount] = charCount + segmentCount; - segments[segmentCount] = charCount; - newChars[charCount + segmentCount++] = separator; - } - if (segmentCount != nSegments) { - int[] tmp = new int [segmentCount]; - System.arraycopy(invalidOffsets, 0, tmp, 0, segmentCount); - invalidOffsets = tmp; - } - return new String(newChars, 0, Math.min(charCount + segmentCount, newChars.length)); -} - -/** - * Returns the line spacing of the receiver. - * - * @return the line spacing - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public int getSpacing () { - checkLayout(); - return spacing; -} - -/** - * Gets the style of the receiver at the specified character offset. - * - * @param offset the text offset - * @return the style or <code>null</code> if not set - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the character offset is out of range</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public TextStyle getStyle (int offset) { - checkLayout(); - int length = text.length(); - if (!(0 <= offset && offset < length)) SWT.error(SWT.ERROR_INVALID_RANGE); - for (int i=1; i<styles.length; i++) { - StyleItem item = styles[i]; - if (item.start > offset) { - return styles[i - 1].style; - } - } - return null; -} - -/** - * Gets all styles of the receiver. - * - * @return the styles - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #getRanges() - * - * @since 3.2 - */ -public TextStyle[] getStyles () { - checkLayout(); - TextStyle[] result = new TextStyle[styles.length]; - int count = 0; - for (int i=0; i<styles.length; i++) { - if (styles[i].style != null) { - result[count++] = styles[i].style; - } - } - if (count != result.length) { - TextStyle[] newResult = new TextStyle[count]; - System.arraycopy(result, 0, newResult, 0, count); - result = newResult; - } - return result; -} - -/** - * Returns the tab list of the receiver. - * - * @return the tab list - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public int[] getTabs() { - checkLayout(); - return tabs; -} - -/** - * Gets the receiver's text, which will be an empty - * string if it has never been set. - * - * @return the receiver's text - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public String getText () { - checkLayout (); - return text; -} - -/** - * Returns the width of the receiver. - * - * @return the width - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public int getWidth () { - checkLayout (); - int[] buffer = new int[1]; - OS.ATSUGetLayoutControl(layout, OS.kATSULineWidthTag, 4, buffer, null); - int wrapWidth = OS.Fix2Long(buffer[0]); - return wrapWidth == 0 ? -1 : wrapWidth; -} - -/* - * Returns true if the underline style is supported natively by ATSUI - */ -static boolean isUnderlineSupported (TextStyle style) { - if (style != null && style.underline) { - int uStyle = style.underlineStyle; - return uStyle == SWT.UNDERLINE_SINGLE || uStyle == SWT.UNDERLINE_DOUBLE || uStyle == SWT.UNDERLINE_LINK; - } - return false; -} - -/** - * Returns <code>true</code> if the text layout has been disposed, - * and <code>false</code> otherwise. - * <p> - * This method gets the dispose state for the text layout. - * When a text layout has been disposed, it is an error to - * invoke any other method using the text layout. - * </p> - * - * @return <code>true</code> when the text layout is disposed and <code>false</code> otherwise - */ -public boolean isDisposed () { - return layout == 0; -} - -/** - * Sets the text alignment for the receiver. The alignment controls - * how a line of text is positioned horizontally. The argument should - * be one of <code>SWT.LEFT</code>, <code>SWT.RIGHT</code> or <code>SWT.CENTER</code>. - * <p> - * The default alignment is <code>SWT.LEFT</code>. Note that the receiver's - * width must be set in order to use <code>SWT.RIGHT</code> or <code>SWT.CENTER</code> - * alignment. - * </p> - * - * @param alignment the new alignment - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #setWidth(int) - */ -public void setAlignment (int alignment) { - checkLayout(); - int mask = SWT.LEFT | SWT.CENTER | SWT.RIGHT; - alignment &= mask; - if (alignment == 0) return; - if (alignment == getAlignment()) return; - freeRuns(); - if ((alignment & SWT.LEFT) != 0) alignment = SWT.LEFT; - if ((alignment & SWT.RIGHT) != 0) alignment = SWT.RIGHT; - int align = OS.kATSUStartAlignment; - switch (alignment) { - case SWT.CENTER: align = OS.kATSUCenterAlignment; break; - case SWT.RIGHT: align = OS.kATSUEndAlignment; break; - } - setLayoutControl(OS.kATSULineFlushFactorTag, align, 4); -} - -/** - * Sets the ascent of the receiver. The ascent is distance in pixels - * from the baseline to the top of the line and it is applied to all - * lines. The default value is <code>-1</code> which means that the - * ascent is calculated from the line fonts. - * - * @param ascent the new ascent - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the ascent is less than <code>-1</code></li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #setDescent(int) - * @see #getLineMetrics(int) - */ -public void setAscent (int ascent) { - checkLayout (); - if (ascent < -1) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - if (this.ascent == ascent) return; - freeRuns(); - this.ascent = ascent; -} - -/** - * Sets the descent of the receiver. The descent is distance in pixels - * from the baseline to the bottom of the line and it is applied to all - * lines. The default value is <code>-1</code> which means that the - * descent is calculated from the line fonts. - * - * @param descent the new descent - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the descent is less than <code>-1</code></li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #setAscent(int) - * @see #getLineMetrics(int) - */ -public void setDescent (int descent) { - checkLayout (); - if (descent < -1) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - if (this.descent == descent) return; - freeRuns(); - this.descent = descent; -} - -void setLayoutControl(int tag, int value, int size) { - int ptr1 = OS.NewPtr(size); - if (size == 1) { - byte[] buffer = new byte[1]; - buffer[0] = (byte) value; - OS.memmove(ptr1, buffer, size); - } else { - int[] buffer = new int[1]; - buffer[0] = value; - OS.memmove(ptr1, buffer, size); - } - int[] tags = new int[]{tag}; - int[] sizes = new int[]{size}; - int[] values = new int[]{ptr1}; - OS.ATSUSetLayoutControls(layout, tags.length, tags, sizes, values); - OS.DisposePtr(ptr1); -} - -/** - * Sets the default font which will be used by the receiver - * to draw and measure text. If the - * argument is null, then a default font appropriate - * for the platform will be used instead. Note that a text - * style can override the default font. - * - * @param font the new font for the receiver, or null to indicate a default font - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the font has been disposed</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void setFont (Font font) { - checkLayout (); - if (font != null && font.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - Font oldFont = this.font; - if (oldFont == font) return; - this.font = font; - if (oldFont != null && oldFont.equals(font)) return; - freeRuns(); -} - -/** - * Sets the indent of the receiver. This indent it applied of the first line of - * each paragraph. - * - * @param indent new indent - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.2 - */ -public void setIndent (int indent) { - checkLayout (); - if (indent < 0) return; - if (this.indent == indent) return; - freeRuns(); - this.indent = indent; -} - -/** - * Sets the justification of the receiver. Note that the receiver's - * width must be set in order to use justification. - * - * @param justify new justify - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.2 - */ -public void setJustify (boolean justify) { - checkLayout (); - if (justify == getJustify()) return; - freeRuns(); - setLayoutControl(OS.kATSULineJustificationFactorTag, justify ? OS.kATSUFullJustification : OS.kATSUNoJustification, 4); -} - -/** - * Sets the orientation of the receiver, which must be one - * of <code>SWT.LEFT_TO_RIGHT</code> or <code>SWT.RIGHT_TO_LEFT</code>. - * - * @param orientation new orientation style - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void setOrientation(int orientation) { - checkLayout(); - int mask = SWT.RIGHT_TO_LEFT | SWT.LEFT_TO_RIGHT; - orientation &= mask; - if (orientation == 0) return; - if ((orientation & SWT.LEFT_TO_RIGHT) != 0) orientation = SWT.LEFT_TO_RIGHT; - if (orientation == getOrientation()) return; - freeRuns(); - int lineDir = OS.kATSULeftToRightBaseDirection; - if (orientation == SWT.RIGHT_TO_LEFT) lineDir = OS.kATSURightToLeftBaseDirection; - setLayoutControl(OS.kATSULineDirectionTag, lineDir, 1); -} - -/** - * Sets the offsets of the receiver's text segments. Text segments are used to - * override the default behaviour of the bidirectional algorithm. - * Bidirectional reordering can happen within a text segment but not - * between two adjacent segments. - * <p> - * Each text segment is determined by two consecutive offsets in the - * <code>segments</code> arrays. The first element of the array should - * always be zero and the last one should always be equals to length of - * the text. - * </p> - * - * @param segments the text segments offset - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void setSegments(int[] segments) { - checkLayout(); - if (this.segments == null && segments == null) return; - if (this.segments != null && segments !=null) { - if (this.segments.length == segments.length) { - int i; - for (i = 0; i <segments.length; i++) { - if (this.segments[i] != segments[i]) break; - } - if (i == segments.length) return; - } - } - freeRuns(); - this.segments = segments; -} - -/** - * Sets the line spacing of the receiver. The line spacing - * is the space left between lines. - * - * @param spacing the new line spacing - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the spacing is negative</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void setSpacing (int spacing) { - checkLayout(); - if (spacing < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - if (this.spacing == spacing) return; - freeRuns(); - this.spacing = spacing; -} - -/** - * Sets the style of the receiver for the specified range. Styles previously - * set for that range will be overwritten. The start and end offsets are - * inclusive and will be clamped if out of range. - * - * @param style the style - * @param start the start offset - * @param end the end offset - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void setStyle (TextStyle style, int start, int end) { - checkLayout(); - int length = text.length(); - if (length == 0) return; - if (start > end) return; - start = Math.min(Math.max(0, start), length - 1); - end = Math.min(Math.max(0, end), length - 1); - int low = -1; - int high = styles.length; - while (high - low > 1) { - int index = (high + low) / 2; - if (styles[index + 1].start > start) { - high = index; - } else { - low = index; - } - } - if (0 <= high && high < styles.length) { - StyleItem item = styles[high]; - if (item.start == start && styles[high + 1].start - 1 == end) { - if (style == null) { - if (item.style == null) return; - } else { - if (style.equals(item.style)) return; - } - } - } - freeRuns(); - int modifyStart = high; - int modifyEnd = modifyStart; - while (modifyEnd < styles.length) { - if (styles[modifyEnd + 1].start > end) break; - modifyEnd++; - } - if (modifyStart == modifyEnd) { - int styleStart = styles[modifyStart].start; - int styleEnd = styles[modifyEnd + 1].start - 1; - if (styleStart == start && styleEnd == end) { - styles[modifyStart].style = style; - return; - } - if (styleStart != start && styleEnd != end) { - StyleItem[] newStyles = new StyleItem[styles.length + 2]; - System.arraycopy(styles, 0, newStyles, 0, modifyStart + 1); - StyleItem item = new StyleItem(); - item.start = start; - item.style = style; - newStyles[modifyStart + 1] = item; - item = new StyleItem(); - item.start = end + 1; - item.style = styles[modifyStart].style; - newStyles[modifyStart + 2] = item; - System.arraycopy(styles, modifyEnd + 1, newStyles, modifyEnd + 3, styles.length - modifyEnd - 1); - styles = newStyles; - return; - } - } - if (start == styles[modifyStart].start) modifyStart--; - if (end == styles[modifyEnd + 1].start - 1) modifyEnd++; - int newLength = styles.length + 1 - (modifyEnd - modifyStart - 1); - StyleItem[] newStyles = new StyleItem[newLength]; - System.arraycopy(styles, 0, newStyles, 0, modifyStart + 1); - StyleItem item = new StyleItem(); - item.start = start; - item.style = style; - newStyles[modifyStart + 1] = item; - styles[modifyEnd].start = end + 1; - System.arraycopy(styles, modifyEnd, newStyles, modifyStart + 2, styles.length - modifyEnd); - styles = newStyles; -} - -/** - * Sets the receiver's tab list. Each value in the tab list specifies - * the space in pixels from the origin of the text layout to the respective - * tab stop. The last tab stop width is repeated continuously. - * - * @param tabs the new tab list - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void setTabs(int[] tabs) { - checkLayout(); - if (this.tabs == null && tabs == null) return; - if (this.tabs != null && tabs !=null) { - if (this.tabs.length == tabs.length) { - int i; - for (i = 0; i <tabs.length; i++) { - if (this.tabs[i] != tabs[i]) break; - } - if (i == tabs.length) return; - } - } - freeRuns(); - this.tabs = tabs; - if (tabsPtr != 0) OS.DisposePtr(tabsPtr); - tabsPtr = 0; - if (tabs == null) { - OS.ATSUSetTabArray(layout, 0, 0); - } else { - ATSUTab tab = new ATSUTab(); - tab.tabPosition = OS.Long2Fix(0); - int length = Math.max(TAB_COUNT, tabs.length); - int ptr = tabsPtr = OS.NewPtr(ATSUTab.sizeof * length), i, offset; - for (i=0, offset=ptr; i<tabs.length; i++, offset += ATSUTab.sizeof) { - tab.tabType = (short)OS.kATSULeftTab; - tab.tabPosition = OS.Long2Fix(tabs[i]); - OS.memmove(offset, tab, ATSUTab.sizeof); - } - int width = i - 2 >= 0 ? tabs[i - 1] - tabs[i - 2] : tabs[i - 1]; - if (width > 0) { - for (; i<length; i++, offset += ATSUTab.sizeof) { - tab.tabType = (short)OS.kATSULeftTab; - tab.tabPosition += OS.Long2Fix(width); - OS.memmove(offset, tab, ATSUTab.sizeof); - } - } - OS.ATSUSetTabArray(layout, ptr, i); - } -} - -/** - * Sets the receiver's text. - *<p> - * Note: Setting the text also clears all the styles. This method - * returns without doing anything if the new text is the same as - * the current text. - * </p> - * - * @param text the new text - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the text is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void setText (String text) { - checkLayout (); - if (text == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (text.equals(this.text)) return; - freeRuns(); - this.text = text; - styles = new StyleItem[2]; - styles[0] = new StyleItem(); - styles[1] = new StyleItem(); - styles[styles.length - 1].start = text.length(); -} - -/** - * Sets the line width of the receiver, which determines how - * text should be wrapped and aligned. The default value is - * <code>-1</code> which means wrapping is disabled. - * - * @param width the new width - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_INVALID_ARGUMENT - if the width is <code>0</code> or less than <code>-1</code></li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @see #setAlignment(int) - */ -public void setWidth (int width) { - checkLayout (); - if (width < -1 || width == 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - if (width == getWidth()) return; - freeRuns(); - setLayoutControl(OS.kATSULineWidthTag, OS.Long2Fix(Math.max(0, width)), 4); -} - -/** - * Returns a string containing a concise, human-readable - * description of the receiver. - * - * @return a string representation of the receiver - */ -public String toString () { - if (isDisposed()) return "TextLayout {*DISPOSED*}"; - return "TextLayout {" + layout + "}"; -} - -/* - * Translate a client offset to an internal offset - */ -int translateOffset(int offset) { - offset++; - for (int i = 0; i < invalidOffsets.length; i++) { - if (offset < invalidOffsets[i]) break; - offset++; - } - return offset; -} - -/* - * Translate an internal offset to a client offset - */ -int untranslateOffset(int offset) { - for (int i = 0; i < invalidOffsets.length; i++) { - if (offset == invalidOffsets[i]) { - offset++; - continue; - } - if (offset < invalidOffsets[i]) { - return Math.max(0, offset - i - 1); - } - } - return Math.max(0, offset - invalidOffsets.length - 1); -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Transform.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Transform.java deleted file mode 100644 index 05cda4af95..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/graphics/Transform.java +++ /dev/null @@ -1,380 +0,0 @@ -/******************************************************************************* - * 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.swt.graphics; - -import org.eclipse.swt.*; -import org.eclipse.swt.internal.Compatibility; -import org.eclipse.swt.internal.carbon.*; - -/** - * Instances of this class represent transformation matrices for - * points expressed as (x, y) pairs of floating point numbers. - * <p> - * Application code must explicitly invoke the <code>Transform.dispose()</code> - * method to release the operating system resources managed by each instance - * when those instances are no longer required. - * </p> - * <p> - * This class requires the operating system's advanced graphics subsystem - * which may not be available on some platforms. - * </p> - * - * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: GraphicsExample</a> - * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> - * - * @since 3.1 - */ -public class Transform extends Resource { - /** - * the OS resource for the Transform - * (Warning: This field is platform dependent) - * <p> - * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT - * public API. It is marked public only so that it can be shared - * within the packages provided by SWT. It is not available on all - * platforms and should never be accessed from application code. - * </p> - */ - public float[] handle; - -/** - * Constructs a new identity Transform. - * <p> - * This operation requires the operating system's advanced - * graphics subsystem which may not be available on some - * platforms. - * </p> - * - * @param device the device on which to allocate the Transform - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES if a handle for the Transform could not be obtained</li> - * </ul> - * - * @see #dispose() - */ -public Transform (Device device) { - this(device, 1, 0, 0, 1, 0, 0); -} - -/** - * Constructs a new Transform given an array of elements that represent the - * matrix that describes the transformation. - * <p> - * This operation requires the operating system's advanced - * graphics subsystem which may not be available on some - * platforms. - * </p> - * - * @param device the device on which to allocate the Transform - * @param elements an array of floats that describe the transformation matrix - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device, or the elements array is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the elements array is too small to hold the matrix values</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES if a handle for the Transform could not be obtained</li> - * </ul> - * - * @see #dispose() - */ -public Transform(Device device, float[] elements) { - this (device, checkTransform(elements)[0], elements[1], elements[2], elements[3], elements[4], elements[5]); -} - -/** - * Constructs a new Transform given all of the elements that represent the - * matrix that describes the transformation. - * <p> - * This operation requires the operating system's advanced - * graphics subsystem which may not be available on some - * platforms. - * </p> - * - * @param device the device on which to allocate the Transform - * @param m11 the first element of the first row of the matrix - * @param m12 the second element of the first row of the matrix - * @param m21 the first element of the second row of the matrix - * @param m22 the second element of the second row of the matrix - * @param dx the third element of the first row of the matrix - * @param dy the third element of the second row of the matrix - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li> - * </ul> - * @exception SWTError <ul> - * <li>ERROR_NO_HANDLES if a handle for the Transform could not be obtained</li> - * </ul> - * - * @see #dispose() - */ -public Transform (Device device, float m11, float m12, float m21, float m22, float dx, float dy) { - super(device); - handle = new float[6]; - OS.CGAffineTransformMake(m11, m12, m21, m22, dx, dy, handle); - if (handle == null) SWT.error(SWT.ERROR_NO_HANDLES); - init(); -} - -static float[] checkTransform(float[] elements) { - if (elements == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (elements.length < 6) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - return elements; -} - -void destroy() { - handle = null; -} - -/** - * Fills the parameter with the values of the transformation matrix - * that the receiver represents, in the order {m11, m12, m21, m22, dx, dy}. - * - * @param elements array to hold the matrix values - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the parameter is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the parameter is too small to hold the matrix values</li> - * </ul> - */ -public void getElements(float[] elements) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (elements == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (elements.length < 6) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - System.arraycopy(handle, 0, elements, 0, handle.length); -} - -/** - * Modifies the receiver such that the matrix it represents becomes the - * identity matrix. - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.4 - */ -public void identity() { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - OS.CGAffineTransformMake(1, 0, 0, 1, 0, 0, handle); -} - -/** - * Modifies the receiver such that the matrix it represents becomes - * the mathematical inverse of the matrix it previously represented. - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * <li>ERROR_CANNOT_INVERT_MATRIX - if the matrix is not invertible</li> - * </ul> - */ -public void invert() { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if ((handle [0] * handle [3] - handle [1] * handle [2]) == 0) { - SWT.error(SWT.ERROR_CANNOT_INVERT_MATRIX); - } - OS.CGAffineTransformInvert(handle, handle); -} - -/** - * Returns <code>true</code> if the Transform has been disposed, - * and <code>false</code> otherwise. - * <p> - * This method gets the dispose state for the Transform. - * When a Transform has been disposed, it is an error to - * invoke any other method using the Transform. - * - * @return <code>true</code> when the Transform is disposed, and <code>false</code> otherwise - */ -public boolean isDisposed() { - return handle == null; -} - -/** - * Returns <code>true</code> if the Transform represents the identity matrix - * and false otherwise. - * - * @return <code>true</code> if the receiver is an identity Transform, and <code>false</code> otherwise - */ -public boolean isIdentity() { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - return handle[0] == 1 && handle[1] == 0 && handle[2] == 0 && handle[3] == 1 && handle[4] == 0 && handle[5] == 0; -} - -/** - * Modifies the receiver such that the matrix it represents becomes the - * the result of multiplying the matrix it previously represented by the - * argument. - * - * @param matrix the matrix to multiply the receiver by - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the parameter is null</li> - * <li>ERROR_INVALID_ARGUMENT - if the parameter has been disposed</li> - * </ul> - */ -public void multiply(Transform matrix) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (matrix == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (matrix.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - OS.CGAffineTransformConcat(matrix.handle, handle, handle); -} - -/** - * Modifies the receiver so that it represents a transformation that is - * equivalent to its previous transformation rotated by the specified angle. - * The angle is specified in degrees and for the identity transform 0 degrees - * is at the 3 o'clock position. A positive value indicates a clockwise rotation - * while a negative value indicates a counter-clockwise rotation. - * - * @param angle the angle to rotate the transformation by - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void rotate(float angle) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - OS.CGAffineTransformRotate(handle, angle * (float)Compatibility.PI / 180, handle); -} - -/** - * Modifies the receiver so that it represents a transformation that is - * equivalent to its previous transformation scaled by (scaleX, scaleY). - * - * @param scaleX the amount to scale in the X direction - * @param scaleY the amount to scale in the Y direction - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void scale(float scaleX, float scaleY) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - OS.CGAffineTransformScale(handle, scaleX, scaleY, handle); -} - -/** - * Modifies the receiver to represent a new transformation given all of - * the elements that represent the matrix that describes that transformation. - * - * @param m11 the first element of the first row of the matrix - * @param m12 the second element of the first row of the matrix - * @param m21 the first element of the second row of the matrix - * @param m22 the second element of the second row of the matrix - * @param dx the third element of the first row of the matrix - * @param dy the third element of the second row of the matrix - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void setElements(float m11, float m12, float m21, float m22, float dx, float dy) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - OS.CGAffineTransformMake(m11, m12, m21, m22, dx, dy, handle); -} - -/** - * Modifies the receiver so that it represents a transformation that is - * equivalent to its previous transformation sheared by (shearX, shearY). - * - * @param shearX the shear factor in the X direction - * @param shearY the shear factor in the Y direction - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - * - * @since 3.4 - */ -public void shear(float shearX, float shearY) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - float[] matrix = {1, shearX, shearY, 1, 0, 0}; - OS.CGAffineTransformConcat(matrix, handle, handle); -} - -/** - * Given an array containing points described by alternating x and y values, - * modify that array such that each point has been replaced with the result of - * applying the transformation represented by the receiver to that point. - * - * @param pointArray an array of alternating x and y values to be transformed - * - * @exception IllegalArgumentException <ul> - * <li>ERROR_NULL_ARGUMENT - if the point array is null</li> - * </ul> - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void transform(float[] pointArray) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (pointArray == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - CGPoint point = new CGPoint(); - int length = pointArray.length / 2; - for (int i = 0, j = 0; i < length; i++, j += 2) { - point.x = pointArray[j]; - point.y = pointArray[j + 1]; - OS.CGPointApplyAffineTransform(point, handle, point); - pointArray[j] = point.x; - pointArray[j + 1] = point.y; - } -} - -/** - * Modifies the receiver so that it represents a transformation that is - * equivalent to its previous transformation translated by (offsetX, offsetY). - * - * @param offsetX the distance to translate in the X direction - * @param offsetY the distance to translate in the Y direction - * - * @exception SWTException <ul> - * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> - * </ul> - */ -public void translate(float offsetX, float offsetY) { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - OS.CGAffineTransformTranslate(handle, offsetX, offsetY, handle); -} - -/** - * Returns a string containing a concise, human-readable - * description of the receiver. - * - * @return a string representation of the receiver - */ -public String toString() { - if (isDisposed()) return "Transform {*DISPOSED*}"; - float[] elements = new float[6]; - getElements(elements); - return "Transform {" + elements [0] + ", " + elements [1] + ", " +elements [2] + ", " +elements [3] + ", " +elements [4] + ", " +elements [5] + "}"; -} - -} |