diff options
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics')
15 files changed, 0 insertions, 15208 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Color.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Color.java deleted file mode 100755 index 3603b53a65..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Color.java +++ /dev/null @@ -1,325 +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.win32.*; -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 int handle; - -/** - * Prevents uninitialized instances from being created outside the package. - */ -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() { - /* - * If this is a palette-based device, - * Decrease the reference count for this color. - * If the reference count reaches 0, the slot may - * be reused when another color is allocated. - */ - int /*long*/ hPal = device.hPalette; - if (hPal != 0) { - int index = OS.GetNearestPaletteIndex(hPal, handle); - int[] colorRefCount = device.colorRefCount; - if (colorRefCount[index] > 0) { - colorRefCount[index]--; - } - } - 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 Color)) return false; - Color color = (Color) object; - return device == color.device && (handle & 0xFFFFFF) == (color.handle & 0xFFFFFF); -} - -/** - * 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 (handle & 0xFF0000) >> 16; -} - -/** - * 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 (handle & 0xFF00) >> 8 ; -} - -/** - * 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 handle & 0xFF; -} - -/** - * 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(handle & 0xFF, (handle & 0xFF00) >> 8, (handle & 0xFF0000) >> 16); -} - -/** - * 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; -} - -/** - * Allocates the operating system resources associated - * with the receiver. - * - * @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_INVALID_ARGUMENT - if the red, green or blue argument is not between 0 and 255</li> - * </ul> - * - * @see #dispose - */ -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); - } - handle = (red & 0xFF) | ((green & 0xFF) << 8) | ((blue & 0xFF) << 16); - - /* If this is not a palette-based device, return */ - int /*long*/ hPal = device.hPalette; - if (hPal == 0) return; - - int[] colorRefCount = device.colorRefCount; - /* Add this color to the default palette now */ - /* First find out if the color already exists */ - int index = OS.GetNearestPaletteIndex(hPal, handle); - /* See if the nearest color actually is the color */ - byte[] entry = new byte[4]; - OS.GetPaletteEntries(hPal, index, 1, entry); - if ((entry[0] == (byte)red) && (entry[1] == (byte)green) && - (entry[2] == (byte)blue)) { - /* Found the color. Increment the ref count and return */ - colorRefCount[index]++; - return; - } - /* Didn't find the color, allocate it now. Find the first free entry */ - int i = 0; - while (i < colorRefCount.length) { - if (colorRefCount[i] == 0) { - index = i; - break; - } - i++; - } - if (i == colorRefCount.length) { - /* No free entries, use the closest one */ - /* Remake the handle from the actual rgbs */ - handle = (entry[0] & 0xFF) | ((entry[1] & 0xFF) << 8) | - ((entry[2] & 0xFF) << 16); - } else { - /* Found a free entry */ - entry = new byte[] { (byte)(red & 0xFF), (byte)(green & 0xFF), (byte)(blue & 0xFF), 0 }; - OS.SetPaletteEntries(hPal, index, 1, entry); - } - colorRefCount[index]++; -} - -/** - * 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 == -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 "Color {*DISPOSED*}"; //$NON-NLS-1$ - return "Color {" + getRed() + ", " + getGreen() + ", " + getBlue() + "}"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ -} - -/** - * 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 - * @return a new color object containing the specified device and handle - */ -public static Color win32_new(Device device, int handle) { - Color color = new Color(device); - color.handle = handle; - return color; -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Cursor.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Cursor.java deleted file mode 100755 index 6c5273cc22..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Cursor.java +++ /dev/null @@ -1,460 +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.win32.*; -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 /*long*/ handle; - - boolean isIcon; - - /** - * data used to create a HAND cursor. - */ - static final byte[] HAND_SOURCE = { - (byte)0xf9,(byte)0xff,(byte)0xff,(byte)0xff, - (byte)0xf0,(byte)0xff,(byte)0xff,(byte)0xff, - (byte)0xf0,(byte)0xff,(byte)0xff,(byte)0xff, - (byte)0xf0,(byte)0xff,(byte)0xff,(byte)0xff, - (byte)0xf0,(byte)0x3f,(byte)0xff,(byte)0xff, - (byte)0xf0,(byte)0x07,(byte)0xff,(byte)0xff, - (byte)0xf0,(byte)0x03,(byte)0xff,(byte)0xff, - (byte)0xf0,(byte)0x00,(byte)0xff,(byte)0xff, - - (byte)0x10,(byte)0x00,(byte)0x7f,(byte)0xff, - (byte)0x00,(byte)0x00,(byte)0x7f,(byte)0xff, - (byte)0x80,(byte)0x00,(byte)0x7f,(byte)0xff, - (byte)0xc0,(byte)0x00,(byte)0x7f,(byte)0xff, - (byte)0xe0,(byte)0x00,(byte)0x7f,(byte)0xff, - (byte)0xf0,(byte)0x00,(byte)0x7f,(byte)0xff, - (byte)0xf8,(byte)0x00,(byte)0xff,(byte)0xff, - (byte)0xfc,(byte)0x01,(byte)0xff,(byte)0xff, - - (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff, - (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff, - (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff, - (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff, - (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff, - (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff, - (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff, - (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff, - - (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff, - (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff, - (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff, - (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff, - (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff, - (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff, - (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff, - (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff - }; - static final byte[] HAND_MASK = { - (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, - (byte)0x06,(byte)0x00,(byte)0x00,(byte)0x00, - (byte)0x06,(byte)0x00,(byte)0x00,(byte)0x00, - (byte)0x06,(byte)0x00,(byte)0x00,(byte)0x00, - (byte)0x06,(byte)0x00,(byte)0x00,(byte)0x00, - (byte)0x06,(byte)0xc0,(byte)0x00,(byte)0x00, - (byte)0x06,(byte)0xd8,(byte)0x00,(byte)0x00, - (byte)0x06,(byte)0xd8,(byte)0x00,(byte)0x00, - - (byte)0x07,(byte)0xdb,(byte)0x00,(byte)0x00, - (byte)0x67,(byte)0xfb,(byte)0x00,(byte)0x00, - (byte)0x3f,(byte)0xff,(byte)0x00,(byte)0x00, - (byte)0x1f,(byte)0xff,(byte)0x00,(byte)0x00, - (byte)0x0f,(byte)0xff,(byte)0x00,(byte)0x00, - (byte)0x07,(byte)0xff,(byte)0x00,(byte)0x00, - (byte)0x03,(byte)0xfe,(byte)0x00,(byte)0x00, - (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, - - (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, - (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, - (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, - (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, - (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, - (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, - (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, - (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, - - (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, - (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, - (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, - (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, - (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, - (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, - (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, - (byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00 - }; - -/** - * 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); - int /*long*/ lpCursorName = 0; - switch (style) { - case SWT.CURSOR_HAND: lpCursorName = OS.IDC_HAND; break; - case SWT.CURSOR_ARROW: lpCursorName = OS.IDC_ARROW; break; - case SWT.CURSOR_WAIT: lpCursorName = OS.IDC_WAIT; break; - case SWT.CURSOR_CROSS: lpCursorName = OS.IDC_CROSS; break; - case SWT.CURSOR_APPSTARTING: lpCursorName = OS.IDC_APPSTARTING; break; - case SWT.CURSOR_HELP: lpCursorName = OS.IDC_HELP; break; - case SWT.CURSOR_SIZEALL: lpCursorName = OS.IDC_SIZEALL; break; - case SWT.CURSOR_SIZENESW: lpCursorName = OS.IDC_SIZENESW; break; - case SWT.CURSOR_SIZENS: lpCursorName = OS.IDC_SIZENS; break; - case SWT.CURSOR_SIZENWSE: lpCursorName = OS.IDC_SIZENWSE; break; - case SWT.CURSOR_SIZEWE: lpCursorName = OS.IDC_SIZEWE; break; - case SWT.CURSOR_SIZEN: lpCursorName = OS.IDC_SIZENS; break; - case SWT.CURSOR_SIZES: lpCursorName = OS.IDC_SIZENS; break; - case SWT.CURSOR_SIZEE: lpCursorName = OS.IDC_SIZEWE; break; - case SWT.CURSOR_SIZEW: lpCursorName = OS.IDC_SIZEWE; break; - case SWT.CURSOR_SIZENE: lpCursorName = OS.IDC_SIZENESW; break; - case SWT.CURSOR_SIZESE: lpCursorName = OS.IDC_SIZENWSE; break; - case SWT.CURSOR_SIZESW: lpCursorName = OS.IDC_SIZENESW; break; - case SWT.CURSOR_SIZENW: lpCursorName = OS.IDC_SIZENWSE; break; - case SWT.CURSOR_UPARROW: lpCursorName = OS.IDC_UPARROW; break; - case SWT.CURSOR_IBEAM: lpCursorName = OS.IDC_IBEAM; break; - case SWT.CURSOR_NO: lpCursorName = OS.IDC_NO; break; - default: - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - handle = OS.LoadCursor(0, lpCursorName); - /* - * IDC_HAND is supported only on Windows 2000 and Windows 98. - * Create a hand cursor if running in other Windows platforms. - */ - if (handle == 0 && style == SWT.CURSOR_HAND) { - int width = OS.GetSystemMetrics(OS.SM_CXCURSOR); - int height = OS.GetSystemMetrics(OS.SM_CYCURSOR); - if (width == 32 && height == 32) { - int /*long*/ hInst = OS.GetModuleHandle(null); - if (OS.IsWinCE) SWT.error(SWT.ERROR_NOT_IMPLEMENTED); - handle = OS.CreateCursor(hInst, 5, 0, 32, 32, HAND_SOURCE, HAND_MASK); - - } - } - if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); - 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); - } - /* Convert depth to 1 */ - mask = ImageData.convertMask(mask); - source = ImageData.convertMask(source); - - /* Make sure source and mask scanline pad is 2 */ - byte[] sourceData = ImageData.convertPad(source.data, source.width, source.height, source.depth, source.scanlinePad, 2); - byte[] maskData = ImageData.convertPad(mask.data, mask.width, mask.height, mask.depth, mask.scanlinePad, 2); - - /* Create the cursor */ - int /*long*/ hInst = OS.GetModuleHandle(null); - if (OS.IsWinCE) SWT.error (SWT.ERROR_NOT_IMPLEMENTED); - handle = OS.CreateCursor(hInst, hotspotX, hotspotY, source.width, source.height, sourceData, maskData); - if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); - init(); -} - -/** - * 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); - /* Check the hotspots */ - if (hotspotX >= source.width || hotspotX < 0 || - hotspotY >= source.height || hotspotY < 0) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - ImageData mask = source.getTransparencyMask(); - int /*long*/ [] result = Image.init(this.device, null, source, mask); - int /*long*/ hBitmap = result[0]; - int /*long*/ hMask = result[1]; - /* Create the icon */ - ICONINFO info = new ICONINFO(); - info.fIcon = false; - info.hbmColor = hBitmap; - info.hbmMask = hMask; - info.xHotspot = hotspotX; - info.yHotspot = hotspotY; - handle = OS.CreateIconIndirect(info); - if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); - OS.DeleteObject(hBitmap); - OS.DeleteObject(hMask); - isIcon = true; - init(); -} - -void destroy () { - /* - * It is an error in Windows to destroy the current - * cursor. Check that the cursor that is about to - * be destroyed is the current cursor. If so, set - * the current cursor to be IDC_ARROW. Note that - * Windows shares predefined cursors so the call to - * LoadCursor() does not leak. - */ - // TEMPORARY CODE -// if (OS.GetCursor() == handle) { -// OS.SetCursor(OS.LoadCursor(0, OS.IDC_ARROW)); -// } - - if (isIcon) { - OS.DestroyIcon(handle); - } else { - /* - * The MSDN states that one should not destroy a shared - * cursor, that is, one obtained from LoadCursor. - * However, it does not appear to do any harm, so rather - * than keep track of how a cursor was created, we just - * destroy them all. If this causes problems in the future, - * put the flag back in. - */ - if (!OS.IsWinCE) OS.DestroyCursor(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 (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 (int)/*64*/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 == 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 "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 - * @return a new cursor object containing the specified device and handle - */ -public static Cursor win32_new(Device device, int handle) { - Cursor cursor = new Cursor(device); - cursor.handle = handle; - return cursor; -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Device.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Device.java deleted file mode 100755 index 7745d9088a..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Device.java +++ /dev/null @@ -1,972 +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.gdip.*; -import org.eclipse.swt.internal.win32.*; -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; - - /** - * Palette - * (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 /*long*/ hPalette = 0; - int [] colorRefCount; - - /* System Font */ - Font systemFont; - - /* Font Enumeration */ - int nFonts = 256; - LOGFONT [] logFonts; - TEXTMETRIC metrics; - int[] pixels; - - /* Scripts */ - int /*long*/ [] scripts; - - /* Advanced Graphics */ - int /*long*/ [] gdipToken; - int /*long*/ fontCollection; - String[] loadedFonts; - - boolean disposed; - - /* - * 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"); //$NON-NLS-1$ - } 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 (); - } -} - -void addFont (String font) { - if (loadedFonts == null) loadedFonts = new String [4]; - int length = loadedFonts.length; - for (int i=0; i<length; i++) { - if (font.equals(loadedFonts [i])) return; - } - int index = 0; - while (index < length) { - if (loadedFonts [index] == null) break; - index++; - } - if (index == length) { - String [] temp = new String [length + 4]; - System.arraycopy (loadedFonts, 0, temp, 0, length); - loadedFonts = temp; - } - loadedFonts [index] = font; -} - -/** - * 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); -} - -void checkGDIP() { - if (gdipToken != null) return; - int oldErrorMode = 0; - if (!OS.IsWinCE) oldErrorMode = OS.SetErrorMode (OS.SEM_FAILCRITICALERRORS); - try { - int /*long*/ [] token = new int /*long*/ [1]; - GdiplusStartupInput input = new GdiplusStartupInput (); - input.GdiplusVersion = 1; - if (Gdip.GdiplusStartup (token, input, 0) == 0) { - gdipToken = token; - if (loadedFonts != null) { - fontCollection = Gdip.PrivateFontCollection_new(); - if (fontCollection == 0) SWT.error(SWT.ERROR_NO_HANDLES); - for (int i = 0; i < loadedFonts.length; i++) { - String path = loadedFonts[i]; - if (path == null) break; - int length = path.length(); - char [] buffer = new char [length + 1]; - path.getChars(0, length, buffer, 0); - Gdip.PrivateFontCollection_AddFontFile(fontCollection, buffer); - } - loadedFonts = null; - } - } - } catch (Throwable t) { - SWT.error (SWT.ERROR_NO_GRAPHICS_LIBRARY, t, " [GDI+ is required]"); //$NON-NLS-1$ - } finally { - if (!OS.IsWinCE) OS.SetErrorMode (oldErrorMode); - } -} - -/** - * 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) { -} - -int computePixels(float height) { - int /*long*/ hDC = internal_new_GC (null); - int pixels = -(int)(0.5f + (height * OS.GetDeviceCaps(hDC, OS.LOGPIXELSY) / 72f)); - internal_dispose_GC (hDC, null); - return pixels; -} - -float computePoints(LOGFONT logFont, int /*long*/ hFont) { - int /*long*/ hDC = internal_new_GC (null); - int logPixelsY = OS.GetDeviceCaps(hDC, OS.LOGPIXELSY); - int pixels = 0; - if (logFont.lfHeight > 0) { - /* - * Feature in Windows. If the lfHeight of the LOGFONT structure - * is positive, the lfHeight measures the height of the entire - * cell, including internal leading, in logical units. Since the - * height of a font in points does not include the internal leading, - * we must subtract the internal leading, which requires a TEXTMETRIC. - */ - int /*long*/ oldFont = OS.SelectObject(hDC, hFont); - TEXTMETRIC lptm = OS.IsUnicode ? (TEXTMETRIC)new TEXTMETRICW() : new TEXTMETRICA(); - OS.GetTextMetrics(hDC, lptm); - OS.SelectObject(hDC, oldFont); - pixels = logFont.lfHeight - lptm.tmInternalLeading; - } else { - pixels = -logFont.lfHeight; - } - internal_dispose_GC (hDC, null); - return pixels * 72f / logPixelsY; -} - -/** - * 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 () { -} - -/** - * 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) { - printErrors (); - 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; - } - } - } -} - -int /*long*/ EnumFontFamProc (int /*long*/ lpelfe, int /*long*/ lpntme, int /*long*/ FontType, int /*long*/ lParam) { - boolean isScalable = ((int)/*64*/FontType & OS.RASTER_FONTTYPE) == 0; - boolean scalable = lParam == 1; - if (isScalable == scalable) { - /* Add the log font to the list of log fonts */ - if (nFonts == logFonts.length) { - LOGFONT [] newLogFonts = new LOGFONT [logFonts.length + 128]; - System.arraycopy (logFonts, 0, newLogFonts, 0, nFonts); - logFonts = newLogFonts; - int[] newPixels = new int[newLogFonts.length]; - System.arraycopy (pixels, 0, newPixels, 0, nFonts); - pixels = newPixels; - } - LOGFONT logFont = logFonts [nFonts]; - if (logFont == null) logFont = OS.IsUnicode ? (LOGFONT)new LOGFONTW () : new LOGFONTA (); - OS.MoveMemory (logFont, lpelfe, LOGFONT.sizeof); - logFonts [nFonts] = logFont; - if (logFont.lfHeight > 0) { - /* - * Feature in Windows. If the lfHeight of the LOGFONT structure - * is positive, the lfHeight measures the height of the entire - * cell, including internal leading, in logical units. Since the - * height of a font in points does not include the internal leading, - * we must subtract the internal leading, which requires a TEXTMETRIC, - * which in turn requires font creation. - */ - OS.MoveMemory(metrics, lpntme, TEXTMETRIC.sizeof); - pixels[nFonts] = logFont.lfHeight - metrics.tmInternalLeading; - } else { - pixels[nFonts] = -logFont.lfHeight; - } - nFonts++; - } - return 1; -} - -/** - * 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 /*long*/ hDC = internal_new_GC (null); - int width = OS.GetDeviceCaps (hDC, OS.HORZRES); - int height = OS.GetDeviceCaps (hDC, OS.VERTRES); - internal_dispose_GC (hDC, null); - return new Rectangle (0, 0, width, height); -} - -/** - * 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 () { - return getBounds (); -} - -/** - * 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 /*long*/ hDC = internal_new_GC (null); - int bits = OS.GetDeviceCaps (hDC, OS.BITSPIXEL); - int planes = OS.GetDeviceCaps (hDC, OS.PLANES); - internal_dispose_GC (hDC, null); - return bits * planes; -} - -/** - * 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 /*long*/ hDC = internal_new_GC (null); - int dpiX = OS.GetDeviceCaps (hDC, OS.LOGPIXELSX); - int dpiY = OS.GetDeviceCaps (hDC, OS.LOGPIXELSY); - internal_dispose_GC (hDC, null); - return new Point (dpiX, dpiY); -} - -/** - * 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 (); - - /* Create the callback */ - Callback callback = new Callback (this, "EnumFontFamProc", 4); //$NON-NLS-1$ - int /*long*/ lpEnumFontFamProc = callback.getAddress (); - if (lpEnumFontFamProc == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS); - - /* Initialize the instance variables */ - metrics = OS.IsUnicode ? (TEXTMETRIC)new TEXTMETRICW() : new TEXTMETRICA(); - pixels = new int[nFonts]; - logFonts = new LOGFONT [nFonts]; - for (int i=0; i<logFonts.length; i++) { - logFonts [i] = OS.IsUnicode ? (LOGFONT) new LOGFONTW () : new LOGFONTA (); - } - nFonts = 0; - - /* Enumerate */ - int offset = 0; - int /*long*/ hDC = internal_new_GC (null); - if (faceName == null) { - /* The user did not specify a face name, so they want all versions of all available face names */ - OS.EnumFontFamilies (hDC, null, lpEnumFontFamProc, scalable ? 1 : 0); - - /** - * For bitmapped fonts, EnumFontFamilies only enumerates once for each font, regardless - * of how many styles are available. If the user wants bitmapped fonts, enumerate on - * each face name now. - */ - offset = nFonts; - for (int i=0; i<offset; i++) { - LOGFONT lf = logFonts [i]; - /** - * Bug in Windows 98. When EnumFontFamiliesEx is called with a specified face name, it - * should enumerate for each available style of that font. Instead, it only enumerates - * once. The fix is to call EnumFontFamilies, which works as expected. - */ - if (OS.IsUnicode) { - OS.EnumFontFamiliesW (hDC, ((LOGFONTW)lf).lfFaceName, lpEnumFontFamProc, scalable ? 1 : 0); - } else { - OS.EnumFontFamiliesA (hDC, ((LOGFONTA)lf).lfFaceName, lpEnumFontFamProc, scalable ? 1 : 0); - } - } - } else { - /* Use the character encoding for the default locale */ - TCHAR lpFaceName = new TCHAR (0, faceName, true); - /** - * Bug in Windows 98. When EnumFontFamiliesEx is called with a specified face name, it - * should enumerate for each available style of that font. Instead, it only enumerates - * once. The fix is to call EnumFontFamilies, which works as expected. - */ - OS.EnumFontFamilies (hDC, lpFaceName, lpEnumFontFamProc, scalable ? 1 : 0); - } - int logPixelsY = OS.GetDeviceCaps(hDC, OS.LOGPIXELSY); - internal_dispose_GC (hDC, null); - - /* Create the fontData from the logfonts */ - int count = 0; - FontData [] result = new FontData [nFonts - offset]; - for (int i=offset; i<nFonts; i++) { - FontData fd = FontData.win32_new (logFonts [i], pixels [i] * 72f / logPixelsY); - int j; - for (j = 0; j < count; j++) { - if (fd.equals (result [j])) break; - } - if (j == count) result [count++] = fd; - } - if (count != result.length) { - FontData [] newResult = new FontData [count]; - System.arraycopy (result, 0, newResult, 0, count); - result = newResult; - } - - /* Clean up */ - callback.dispose (); - logFonts = null; - pixels = null; - metrics = null; - return result; -} - -String getLastError () { - int error = OS.GetLastError(); - if (error == 0) return ""; //$NON-NLS-1$ - return " [GetLastError=0x" + Integer.toHexString(error) + "]"; //$NON-NLS-1$ //$NON-NLS-2$ -} - -String getLastErrorText () { - int error = OS.GetLastError(); - if (error == 0) return ""; //$NON-NLS-1$ - int /*long*/ [] buffer = new int /*long*/ [1]; - int dwFlags = OS.FORMAT_MESSAGE_ALLOCATE_BUFFER | OS.FORMAT_MESSAGE_FROM_SYSTEM | OS.FORMAT_MESSAGE_IGNORE_INSERTS; - int length = OS.FormatMessage(dwFlags, 0, error, OS.LANG_USER_DEFAULT, buffer, 0, 0); - if (length == 0) return " [GetLastError=0x" + Integer.toHexString(error) + "]"; //$NON-NLS-1$ //$NON-NLS-2$ - TCHAR buffer1 = new TCHAR(0, length); - OS.MoveMemory(buffer1, buffer[0], length * TCHAR.sizeof); - if (buffer[0] != 0) OS.LocalFree(buffer[0]); - return buffer1.toString(0, length); -} - -/** - * 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 (); - int pixel = 0x00000000; - switch (id) { - case SWT.COLOR_WHITE: pixel = 0x00FFFFFF; break; - case SWT.COLOR_BLACK: pixel = 0x00000000; break; - case SWT.COLOR_RED: pixel = 0x000000FF; break; - case SWT.COLOR_DARK_RED: pixel = 0x00000080; break; - case SWT.COLOR_GREEN: pixel = 0x0000FF00; break; - case SWT.COLOR_DARK_GREEN: pixel = 0x00008000; break; - case SWT.COLOR_YELLOW: pixel = 0x0000FFFF; break; - case SWT.COLOR_DARK_YELLOW: pixel = 0x00008080; break; - case SWT.COLOR_BLUE: pixel = 0x00FF0000; break; - case SWT.COLOR_DARK_BLUE: pixel = 0x00800000; break; - case SWT.COLOR_MAGENTA: pixel = 0x00FF00FF; break; - case SWT.COLOR_DARK_MAGENTA: pixel = 0x00800080; break; - case SWT.COLOR_CYAN: pixel = 0x00FFFF00; break; - case SWT.COLOR_DARK_CYAN: pixel = 0x00808000; break; - case SWT.COLOR_GRAY: pixel = 0x00C0C0C0; break; - case SWT.COLOR_DARK_GRAY: pixel = 0x00808080; break; - } - return Color.win32_new (this, pixel); -} - -/** - * 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 (); - int /*long*/ hFont = OS.GetStockObject (OS.SYSTEM_FONT); - return Font.win32_new (this, hFont); -} - -/** - * 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 false; -} - -/** - * 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 () { - if (debug) { - if (!OS.IsWinCE) OS.GdiSetBatchLimit(1); - } - - /* Initialize the system font slot */ - systemFont = getSystemFont(); - - /* Initialize scripts list */ - if (!OS.IsWinCE) { - int /*long*/ [] ppSp = new int /*long*/ [1]; - int [] piNumScripts = new int [1]; - OS.ScriptGetProperties (ppSp, piNumScripts); - scripts = new int /*long*/ [piNumScripts [0]]; - OS.MoveMemory (scripts, ppSp [0], scripts.length * OS.PTR_SIZEOF); - } - - /* - * If we're not on a device which supports palettes, - * don't create one. - */ - int /*long*/ hDC = internal_new_GC (null); - int rc = OS.GetDeviceCaps (hDC, OS.RASTERCAPS); - int bits = OS.GetDeviceCaps (hDC, OS.BITSPIXEL); - int planes = OS.GetDeviceCaps (hDC, OS.PLANES); - - bits *= planes; - if ((rc & OS.RC_PALETTE) == 0 || bits != 8) { - internal_dispose_GC (hDC, null); - return; - } - - int numReserved = OS.GetDeviceCaps (hDC, OS.NUMRESERVED); - int numEntries = OS.GetDeviceCaps (hDC, OS.SIZEPALETTE); - - if (OS.IsWinCE) { - /* - * Feature on WinCE. For some reason, certain 8 bit WinCE - * devices return 0 for the number of reserved entries in - * the system palette. Their system palette correctly contains - * the usual 20 system colors. The workaround is to assume - * there are 20 reserved system colors instead of 0. - */ - if (numReserved == 0 && numEntries >= 20) numReserved = 20; - } - - /* Create the palette and reference counter */ - colorRefCount = new int [numEntries]; - - /* 4 bytes header + 4 bytes per entry * numEntries entries */ - byte [] logPalette = new byte [4 + 4 * numEntries]; - - /* 2 bytes = special header */ - logPalette [0] = 0x00; - logPalette [1] = 0x03; - - /* 2 bytes = number of colors, LSB first */ - logPalette [2] = 0; - logPalette [3] = 1; - - /* - * Create a palette which contains the system entries - * as they are located in the system palette. The - * MSDN article 'Memory Device Contexts' describes - * where system entries are located. On an 8 bit - * display with 20 reserved colors, the system colors - * will be the first 10 entries and the last 10 ones. - */ - byte[] lppe = new byte [4 * numEntries]; - OS.GetSystemPaletteEntries (hDC, 0, numEntries, lppe); - /* Copy all entries from the system palette */ - System.arraycopy (lppe, 0, logPalette, 4, 4 * numEntries); - /* Lock the indices corresponding to the system entries */ - for (int i = 0; i < numReserved / 2; i++) { - colorRefCount [i] = 1; - colorRefCount [numEntries - 1 - i] = 1; - } - internal_dispose_GC (hDC, null); - hPalette = OS.CreatePalette (logPalette); -} -/** - * 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 /*long*/ 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 /*long*/ internal_dispose_GC (int /*long*/ hDC, 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); - if (OS.IsWinNT && OS.WIN32_VERSION >= OS.VERSION (4, 10)) { - TCHAR lpszFilename = new TCHAR (0, path, true); - boolean loaded = OS.AddFontResourceEx (lpszFilename, OS.FR_PRIVATE, 0) != 0; - if (loaded) { - if (gdipToken != null) { - if (fontCollection == 0) { - fontCollection = Gdip.PrivateFontCollection_new(); - if (fontCollection == 0) SWT.error(SWT.ERROR_NO_HANDLES); - } - int length = path.length(); - char [] buffer = new char [length + 1]; - path.getChars(0, length, buffer, 0); - Gdip.PrivateFontCollection_AddFontFile(fontCollection, buffer); - } else { - addFont(path); - } - } - return loaded; - } - return false; -} - -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; - } -} - -void printErrors () { - if (!DEBUG) return; - if (tracking) { - synchronized (trackingLock) { - if (objects == null || errors == null) return; - int objectCount = 0; - int colors = 0, cursors = 0, fonts = 0, gcs = 0, images = 0; - int paths = 0, patterns = 0, regions = 0, textLayouts = 0, transforms = 0; - for (int i=0; i<objects.length; i++) { - Object object = objects [i]; - if (object != null) { - objectCount++; - if (object instanceof Color) colors++; - if (object instanceof Cursor) cursors++; - if (object instanceof Font) fonts++; - if (object instanceof GC) gcs++; - if (object instanceof Image) images++; - if (object instanceof Path) paths++; - if (object instanceof Pattern) patterns++; - if (object instanceof Region) regions++; - if (object instanceof TextLayout) textLayouts++; - if (object instanceof Transform) transforms++; - } - } - if (objectCount != 0) { - String string = "Summary: "; - if (colors != 0) string += colors + " Color(s), "; - if (cursors != 0) string += cursors + " Cursor(s), "; - if (fonts != 0) string += fonts + " Font(s), "; - if (gcs != 0) string += gcs + " GC(s), "; - if (images != 0) string += images + " Image(s), "; - if (paths != 0) string += paths + " Path(s), "; - if (patterns != 0) string += patterns + " Pattern(s), "; - if (regions != 0) string += regions + " Region(s), "; - if (textLayouts != 0) string += textLayouts + " TextLayout(s), "; - if (transforms != 0) string += transforms + " Transforms(s), "; - if (string.length () != 0) { - string = string.substring (0, string.length () - 2); - System.err.println (string); - } - for (int i=0; i<errors.length; i++) { - if (errors [i] != null) errors [i].printStackTrace (System.err); - } - } - } - } -} - -/** - * 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 (gdipToken != null) { - if (fontCollection != 0) { - Gdip.PrivateFontCollection_delete(fontCollection); - } - fontCollection = 0; - Gdip.GdiplusShutdown (gdipToken[0]); - } - gdipToken = null; - scripts = null; - if (hPalette != 0) OS.DeleteObject (hPalette); - hPalette = 0; - colorRefCount = null; - logFonts = null; - nFonts = 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 (); -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/DeviceData.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/DeviceData.java deleted file mode 100755 index 9b95c99718..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/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/win32/org/eclipse/swt/graphics/Font.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Font.java deleted file mode 100755 index 23cc7aa24f..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Font.java +++ /dev/null @@ -1,258 +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.win32.*; -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 /*long*/ handle; - -/** - * Prevents uninitialized instances from being created outside the package. - */ -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); - init(fd); - 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); - } - init(fds[0]); - 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); - if (name == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - init(new FontData (name, height, style)); - init(); -} - -/*public*/ Font(Device device, String name, float height, int style) { - super(device); - if (name == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - init(new FontData (name, height, style)); - init(); -} -void destroy() { - OS.DeleteObject(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 (object == this) return true; - if (!(object instanceof Font)) return false; - Font font = (Font) object; - return device == font.device && handle == font.handle; -} - -/** - * 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); - LOGFONT logFont = OS.IsUnicode ? (LOGFONT)new LOGFONTW() : new LOGFONTA(); - OS.GetObject(handle, LOGFONT.sizeof, logFont); - return new FontData[] {FontData.win32_new(logFont, device.computePoints(logFont, 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 (int)/*64*/handle; -} - -void init (FontData fd) { - if (fd == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - LOGFONT logFont = fd.data; - int lfHeight = logFont.lfHeight; - logFont.lfHeight = device.computePixels(fd.height); - handle = OS.CreateFontIndirect(logFont); - logFont.lfHeight = lfHeight; - if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); -} - -/** - * 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 + "}"; -} - -/** - * 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 - * @return a new font object containing the specified device and handle - */ -public static Font win32_new(Device device, int /*long*/ handle) { - Font font = new Font(device); - font.handle = handle; - return font; -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/FontData.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/FontData.java deleted file mode 100755 index 15e6cb2472..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/FontData.java +++ /dev/null @@ -1,669 +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.win32.*; -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 { - - /** - * A Win32 LOGFONT struct - * (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 LOGFONT data; - - /** - * 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 locales of the font - */ - String lang, country, variant; - -/** - * Constructs a new uninitialized font data. - */ -public FontData() { - data = OS.IsUnicode ? (LOGFONT)new LOGFONTW() : new LOGFONTA(); - // We set the charset field so that - // wildcard searching will work properly - // out of the box - data.lfCharSet = (byte)OS.DEFAULT_CHARSET; - height = 12; -} - -/** - * Constructs a new font data given the Windows <code>LOGFONT</code> - * that it should represent. - * - * @param data the <code>LOGFONT</code> for the result - */ -FontData(LOGFONT data, float height) { - this.data = data; - this.height = height; -} - -/** - * 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); - data = OS.IsUnicode ? (LOGFONT)new LOGFONTW() : new LOGFONTA(); - data.lfCharSet = (byte)OS.DEFAULT_CHARSET; - 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("WINDOWS") && version2.equals("1")) { //$NON-NLS-1$//$NON-NLS-2$ - LOGFONT newData = OS.IsUnicode ? (LOGFONT)new LOGFONTW() : new LOGFONTA(); - try { - start = end + 1; - end = string.indexOf('|', start); - if (end == -1) return; - newData.lfHeight = Integer.parseInt(string.substring(start, end)); - start = end + 1; - end = string.indexOf('|', start); - if (end == -1) return; - newData.lfWidth = Integer.parseInt(string.substring(start, end)); - start = end + 1; - end = string.indexOf('|', start); - if (end == -1) return; - newData.lfEscapement = Integer.parseInt(string.substring(start, end)); - start = end + 1; - end = string.indexOf('|', start); - if (end == -1) return; - newData.lfOrientation = Integer.parseInt(string.substring(start, end)); - start = end + 1; - end = string.indexOf('|', start); - if (end == -1) return; - newData.lfWeight = Integer.parseInt(string.substring(start, end)); - start = end + 1; - end = string.indexOf('|', start); - if (end == -1) return; - newData.lfItalic = Byte.parseByte(string.substring(start, end)); - start = end + 1; - end = string.indexOf('|', start); - if (end == -1) return; - newData.lfUnderline = Byte.parseByte(string.substring(start, end)); - start = end + 1; - end = string.indexOf('|', start); - if (end == -1) return; - newData.lfStrikeOut = Byte.parseByte(string.substring(start, end)); - start = end + 1; - end = string.indexOf('|', start); - if (end == -1) return; - newData.lfCharSet = Byte.parseByte(string.substring(start, end)); - start = end + 1; - end = string.indexOf('|', start); - if (end == -1) return; - newData.lfOutPrecision = Byte.parseByte(string.substring(start, end)); - start = end + 1; - end = string.indexOf('|', start); - if (end == -1) return; - newData.lfClipPrecision = Byte.parseByte(string.substring(start, end)); - start = end + 1; - end = string.indexOf('|', start); - if (end == -1) return; - newData.lfQuality = Byte.parseByte(string.substring(start, end)); - start = end + 1; - end = string.indexOf('|', start); - if (end == -1) return; - newData.lfPitchAndFamily = Byte.parseByte(string.substring(start, end)); - start = end + 1; - } catch (NumberFormatException e) { - setName(name); - setHeight(height); - setStyle(style); - return; - } - TCHAR buffer = new TCHAR(0, string.substring(start), false); - int length = Math.min(OS.LF_FACESIZE - 1, buffer.length()); - if (OS.IsUnicode) { - char[] lfFaceName = ((LOGFONTW)newData).lfFaceName; - System.arraycopy(buffer.chars, 0, lfFaceName, 0, length); - } else { - byte[] lfFaceName = ((LOGFONTA)newData).lfFaceName; - System.arraycopy(buffer.bytes, 0, lfFaceName, 0, length); - } - data = newData; - } -} - -/** - * 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) { - if (name == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - data = OS.IsUnicode ? (LOGFONT)new LOGFONTW() : new LOGFONTA(); - setName(name); - setHeight(height); - setStyle(style); - // We set the charset field so that - // wildcard searching will work properly - // out of the box - data.lfCharSet = (byte)OS.DEFAULT_CHARSET; -} - -/*public*/ FontData(String name, float height, int style) { - if (name == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - data = OS.IsUnicode ? (LOGFONT)new LOGFONTW() : new LOGFONTA(); - setName(name); - setHeight(height); - setStyle(style); - // We set the charset field so that - // wildcard searching will work properly - // out of the box - data.lfCharSet = (byte)OS.DEFAULT_CHARSET; -} - -/** - * 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 fd = (FontData)object; - LOGFONT lf = fd.data; - return data.lfCharSet == lf.lfCharSet && - /* - * This code is intentionally commented. When creating - * a FontData, lfHeight is not necessarily set. Instead - * we check the height field which is always set. - */ -// data.lfHeight == lf.lfHeight && - height == fd.height && - data.lfWidth == lf.lfWidth && - data.lfEscapement == lf.lfEscapement && - data.lfOrientation == lf.lfOrientation && - data.lfWeight == lf.lfWeight && - data.lfItalic == lf.lfItalic && - data.lfUnderline == lf.lfUnderline && - data.lfStrikeOut == lf.lfStrikeOut && - data.lfCharSet == lf.lfCharSet && - data.lfOutPrecision == lf.lfOutPrecision && - data.lfClipPrecision == lf.lfClipPrecision && - data.lfQuality == lf.lfQuality && - data.lfPitchAndFamily == lf.lfPitchAndFamily && - getName().equals(fd.getName()); -} - -int /*long*/ EnumLocalesProc(int /*long*/ lpLocaleString) { - - /* Get the locale ID */ - int length = 8; - TCHAR buffer = new TCHAR(0, length); - int byteCount = length * TCHAR.sizeof; - OS.MoveMemory(buffer, lpLocaleString, byteCount); - int lcid = Integer.parseInt(buffer.toString(0, buffer.strlen ()), 16); - - /* Check the language */ - int size = OS.GetLocaleInfo(lcid, OS.LOCALE_SISO639LANGNAME, buffer, length); - if (size <= 0 || !lang.equals(buffer.toString(0, size - 1))) return 1; - - /* Check the country */ - if (country != null) { - size = OS.GetLocaleInfo(lcid, OS.LOCALE_SISO3166CTRYNAME, buffer, length); - if (size <= 0 || !country.equals(buffer.toString(0, size - 1))) return 1; - } - - /* Get the charset */ - size = OS.GetLocaleInfo(lcid, OS.LOCALE_IDEFAULTANSICODEPAGE, buffer, length); - if (size <= 0) return 1; - int cp = Integer.parseInt(buffer.toString(0, size - 1)); - int [] lpCs = new int[8]; - OS.TranslateCharsetInfo(cp, lpCs, OS.TCI_SRCCODEPAGE); - data.lfCharSet = (byte)lpCs[0]; - - return 0; -} - -/** - * Returns the height of the receiver in points. - * - * @return the height of this FontData - * - * @see #setHeight(int) - */ -public int getHeight() { - return (int)(0.5f + 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() { - char[] chars; - if (OS.IsUnicode) { - chars = ((LOGFONTW)data).lfFaceName; - } else { - chars = new char[OS.LF_FACESIZE]; - byte[] bytes = ((LOGFONTA)data).lfFaceName; - OS.MultiByteToWideChar (OS.CP_ACP, OS.MB_PRECOMPOSED, bytes, bytes.length, chars, chars.length); - } - int index = 0; - while (index < chars.length) { - if (chars [index] == 0) break; - index++; - } - return new String (chars, 0, index); -} - -/** - * 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() { - int style = SWT.NORMAL; - if (data.lfWeight == 700) style |= SWT.BOLD; - if (data.lfItalic != 0) style |= SWT.ITALIC; - 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 data.lfCharSet ^ getHeight() ^ data.lfWidth ^ data.lfEscapement ^ - data.lfOrientation ^ data.lfWeight ^ data.lfItalic ^data.lfUnderline ^ - data.lfStrikeOut ^ data.lfCharSet ^ data.lfOutPrecision ^ - data.lfClipPrecision ^ data.lfQuality ^ data.lfPitchAndFamily ^ - getName().hashCode(); -} - -/** - * 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); - } - if (lang == null) { - data.lfCharSet = (byte)OS.DEFAULT_CHARSET; - } else { - Callback callback = new Callback (this, "EnumLocalesProc", 1); //$NON-NLS-1$ - int /*long*/ lpEnumLocalesProc = callback.getAddress (); - if (lpEnumLocalesProc == 0) SWT.error(SWT.ERROR_NO_MORE_CALLBACKS); - OS.EnumSystemLocales(lpEnumLocalesProc, OS.LCID_SUPPORTED); - callback.dispose (); - } -} - -/** - * 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); - - /* The field lfFaceName must be NULL terminated */ - TCHAR buffer = new TCHAR(0, name, true); - int length = Math.min(OS.LF_FACESIZE - 1, buffer.length()); - if (OS.IsUnicode) { - char[] lfFaceName = ((LOGFONTW)data).lfFaceName; - for (int i = 0; i < lfFaceName.length; i++) lfFaceName[i] = 0; - System.arraycopy(buffer.chars, 0, lfFaceName, 0, length); - } else { - byte[] lfFaceName = ((LOGFONTA)data).lfFaceName; - for (int i = 0; i < lfFaceName.length; i++) lfFaceName[i] = 0; - System.arraycopy(buffer.bytes, 0, lfFaceName, 0, length); - } -} - -/** - * 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) { - if ((style & SWT.BOLD) == SWT.BOLD) { - data.lfWeight = 700; - } else { - data.lfWeight = 0; - } - if ((style & SWT.ITALIC) == SWT.ITALIC) { - data.lfItalic = 1; - } else { - data.lfItalic = 0; - } -} - -/** - * 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|"); //$NON-NLS-1$ - String name = getName(); - buffer.append(name); - buffer.append("|"); //$NON-NLS-1$ - buffer.append(getHeightF()); - buffer.append("|"); //$NON-NLS-1$ - buffer.append(getStyle()); - buffer.append("|"); //$NON-NLS-1$ - buffer.append("WINDOWS|1|"); //$NON-NLS-1$ - buffer.append(data.lfHeight); - buffer.append("|"); //$NON-NLS-1$ - buffer.append(data.lfWidth); - buffer.append("|"); //$NON-NLS-1$ - buffer.append(data.lfEscapement); - buffer.append("|"); //$NON-NLS-1$ - buffer.append(data.lfOrientation); - buffer.append("|"); //$NON-NLS-1$ - buffer.append(data.lfWeight); - buffer.append("|"); //$NON-NLS-1$ - buffer.append(data.lfItalic); - buffer.append("|"); //$NON-NLS-1$ - buffer.append(data.lfUnderline); - buffer.append("|"); //$NON-NLS-1$ - buffer.append(data.lfStrikeOut); - buffer.append("|"); //$NON-NLS-1$ - buffer.append(data.lfCharSet); - buffer.append("|"); //$NON-NLS-1$ - buffer.append(data.lfOutPrecision); - buffer.append("|"); //$NON-NLS-1$ - buffer.append(data.lfClipPrecision); - buffer.append("|"); //$NON-NLS-1$ - buffer.append(data.lfQuality); - buffer.append("|"); //$NON-NLS-1$ - buffer.append(data.lfPitchAndFamily); - buffer.append("|"); //$NON-NLS-1$ - buffer.append(name); - return buffer.toString(); -} - -/** - * Invokes platform specific functionality to allocate a new font data. - * <p> - * <b>IMPORTANT:</b> This method is <em>not</em> part of the public - * API for <code>FontData</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 <code>LOGFONT</code> for the font data - * @param height the height of the font data - * @return a new font data object containing the specified <code>LOGFONT</code> and height - */ -public static FontData win32_new(LOGFONT data, float height) { - return new FontData(data, height); -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/FontMetrics.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/FontMetrics.java deleted file mode 100755 index bfa851cd98..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/FontMetrics.java +++ /dev/null @@ -1,183 +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.win32.*; - -/** - * 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 { - - /** - * On Windows, handle is a Win32 TEXTMETRIC struct - * On Photon, handle is a Photon FontQueryInfo struct - * (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 TEXTMETRIC handle; - -/** - * Prevents instances from being created outside the package. - */ -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; - TEXTMETRIC metric = ((FontMetrics)object).handle; - return handle.tmHeight == metric.tmHeight && - handle.tmAscent == metric.tmAscent && - handle.tmDescent == metric.tmDescent && - handle.tmInternalLeading == metric.tmInternalLeading && - handle.tmExternalLeading == metric.tmExternalLeading && - handle.tmAveCharWidth == metric.tmAveCharWidth && - handle.tmMaxCharWidth == metric.tmMaxCharWidth && - handle.tmWeight == metric.tmWeight && - handle.tmOverhang == metric.tmOverhang && - handle.tmDigitizedAspectX == metric.tmDigitizedAspectX && - handle.tmDigitizedAspectY == metric.tmDigitizedAspectY && -// handle.tmFirstChar == metric.tmFirstChar && -// handle.tmLastChar == metric.tmLastChar && -// handle.tmDefaultChar == metric.tmDefaultChar && -// handle.tmBreakChar == metric.tmBreakChar && - handle.tmItalic == metric.tmItalic && - handle.tmUnderlined == metric.tmUnderlined && - handle.tmStruckOut == metric.tmStruckOut && - handle.tmPitchAndFamily == metric.tmPitchAndFamily && - handle.tmCharSet == metric.tmCharSet; -} - -/** - * 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 handle.tmAscent - handle.tmInternalLeading; -} - -/** - * 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 handle.tmAveCharWidth; -} - -/** - * 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 handle.tmDescent; -} - -/** - * 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 handle.tmHeight; -} - -/** - * 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 handle.tmInternalLeading; -} - -/** - * 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.tmHeight ^ handle.tmAscent ^ handle.tmDescent ^ - handle.tmInternalLeading ^ handle.tmExternalLeading ^ - handle.tmAveCharWidth ^ handle.tmMaxCharWidth ^ handle.tmWeight ^ - handle.tmOverhang ^ handle.tmDigitizedAspectX ^ handle.tmDigitizedAspectY ^ -// handle.tmFirstChar ^ handle.tmLastChar ^ handle.tmDefaultChar ^ handle.tmBreakChar ^ - handle.tmItalic ^ handle.tmUnderlined ^ handle.tmStruckOut ^ - handle.tmPitchAndFamily ^ handle.tmCharSet; -} - -/** - * Invokes platform specific functionality to allocate a new font metrics. - * <p> - * <b>IMPORTANT:</b> This method is <em>not</em> part of the public - * API for <code>FontMetrics</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 handle the <code>TEXTMETRIC</code> containing information about a font - * @return a new font metrics object containing the specified <code>TEXTMETRIC</code> - */ -public static FontMetrics win32_new(TEXTMETRIC handle) { - FontMetrics fontMetrics = new FontMetrics(); - fontMetrics.handle = handle; - return fontMetrics; -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java deleted file mode 100755 index e08cbf3e48..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java +++ /dev/null @@ -1,4979 +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.gdip.*; -import org.eclipse.swt.internal.win32.*; -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 /*long*/ handle; - - Drawable drawable; - GCData data; - - static final int FOREGROUND = 1 << 0; - static final int BACKGROUND = 1 << 1; - static final int FONT = 1 << 2; - static final int LINE_STYLE = 1 << 3; - static final int LINE_WIDTH = 1 << 4; - static final int LINE_CAP = 1 << 5; - static final int LINE_JOIN = 1 << 6; - static final int LINE_MITERLIMIT = 1 << 7; - static final int FOREGROUND_TEXT = 1 << 8; - static final int BACKGROUND_TEXT = 1 << 9; - static final int BRUSH = 1 << 10; - static final int PEN = 1 << 11; - static final int NULL_BRUSH = 1 << 12; - static final int NULL_PEN = 1 << 13; - static final int DRAW_OFFSET = 1 << 14; - - static final int DRAW = FOREGROUND | LINE_STYLE | LINE_WIDTH | LINE_CAP | LINE_JOIN | LINE_MITERLIMIT | PEN | NULL_BRUSH | DRAW_OFFSET; - static final int FILL = BACKGROUND | BRUSH | NULL_PEN; - - 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}; - -/** - * Prevents uninitialized instances from being created outside the package. - */ -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, SWT.NONE); -} - -/** - * 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 /*long*/ hDC = 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, hDC); - 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); -} - -void checkGC(int mask) { - int state = data.state; - if ((state & mask) == mask) return; - state = (state ^ mask) & mask; - data.state |= mask; - int /*long*/ gdipGraphics = data.gdipGraphics; - if (gdipGraphics != 0) { - int /*long*/ pen = data.gdipPen; - float width = data.lineWidth; - if ((state & FOREGROUND) != 0 || (pen == 0 && (state & (LINE_WIDTH | LINE_STYLE | LINE_MITERLIMIT | LINE_JOIN | LINE_CAP)) != 0)) { - if (data.gdipFgBrush != 0) Gdip.SolidBrush_delete(data.gdipFgBrush); - data.gdipFgBrush = 0; - int /*long*/ brush; - Pattern pattern = data.foregroundPattern; - if (pattern != null) { - brush = pattern.handle; - if ((data.style & SWT.MIRRORED) != 0) { - switch (Gdip.Brush_GetType(brush)) { - case Gdip.BrushTypeTextureFill: - brush = Gdip.Brush_Clone(brush); - if (brush == 0) SWT.error(SWT.ERROR_NO_HANDLES); - Gdip.TextureBrush_ScaleTransform(brush, -1, 1, Gdip.MatrixOrderPrepend); - data.gdipFgBrush = brush; - } - } - } else { - int foreground = data.foreground; - int rgb = ((foreground >> 16) & 0xFF) | (foreground & 0xFF00) | ((foreground & 0xFF) << 16); - int /*long*/ color = Gdip.Color_new(data.alpha << 24 | rgb); - if (color == 0) SWT.error(SWT.ERROR_NO_HANDLES); - brush = Gdip.SolidBrush_new(color); - if (brush == 0) SWT.error(SWT.ERROR_NO_HANDLES); - Gdip.Color_delete(color); - data.gdipFgBrush = brush; - } - if (pen != 0) { - Gdip.Pen_SetBrush(pen, brush); - } else { - pen = data.gdipPen = Gdip.Pen_new(brush, width); - } - } - if ((state & LINE_WIDTH) != 0) { - Gdip.Pen_SetWidth(pen, width); - switch (data.lineStyle) { - case SWT.LINE_CUSTOM: - state |= LINE_STYLE; - } - } - if ((state & LINE_STYLE) != 0) { - float[] dashes = null; - float dashOffset = 0; - int dashStyle = Gdip.DashStyleSolid; - switch (data.lineStyle) { - case SWT.LINE_SOLID: break; - case SWT.LINE_DOT: dashStyle = Gdip.DashStyleDot; if (width == 0) dashes = LINE_DOT_ZERO; break; - case SWT.LINE_DASH: dashStyle = Gdip.DashStyleDash; if (width == 0) dashes = LINE_DASH_ZERO; break; - case SWT.LINE_DASHDOT: dashStyle = Gdip.DashStyleDashDot; if (width == 0) dashes = LINE_DASHDOT_ZERO; break; - case SWT.LINE_DASHDOTDOT: dashStyle = Gdip.DashStyleDashDotDot; if (width == 0) dashes = LINE_DASHDOTDOT_ZERO; break; - case SWT.LINE_CUSTOM: { - if (data.lineDashes != null) { - dashOffset = data.lineDashesOffset / Math.max (1, width); - dashes = new float[data.lineDashes.length * 2]; - for (int i = 0; i < data.lineDashes.length; i++) { - float dash = data.lineDashes[i] / Math.max (1, width); - dashes[i] = dash; - dashes[i + data.lineDashes.length] = dash; - } - } - } - } - if (dashes != null) { - Gdip.Pen_SetDashPattern(pen, dashes, dashes.length); - Gdip.Pen_SetDashStyle(pen, Gdip.DashStyleCustom); - Gdip.Pen_SetDashOffset(pen, dashOffset); - } else { - Gdip.Pen_SetDashStyle(pen, dashStyle); - } - } - if ((state & LINE_MITERLIMIT) != 0) { - Gdip.Pen_SetMiterLimit(pen, data.lineMiterLimit); - } - if ((state & LINE_JOIN) != 0) { - int joinStyle = 0; - switch (data.lineJoin) { - case SWT.JOIN_MITER: joinStyle = Gdip.LineJoinMiter; break; - case SWT.JOIN_BEVEL: joinStyle = Gdip.LineJoinBevel; break; - case SWT.JOIN_ROUND: joinStyle = Gdip.LineJoinRound; break; - } - Gdip.Pen_SetLineJoin(pen, joinStyle); - } - if ((state & LINE_CAP) != 0) { - int dashCap = Gdip.DashCapFlat, capStyle = 0; - switch (data.lineCap) { - case SWT.CAP_FLAT: capStyle = Gdip.LineCapFlat; break; - case SWT.CAP_ROUND: capStyle = Gdip.LineCapRound; dashCap = Gdip.DashCapRound; break; - case SWT.CAP_SQUARE: capStyle = Gdip.LineCapSquare; break; - } - Gdip.Pen_SetLineCap(pen, capStyle, capStyle, dashCap); - } - if ((state & BACKGROUND) != 0) { - if (data.gdipBgBrush != 0) Gdip.SolidBrush_delete(data.gdipBgBrush); - data.gdipBgBrush = 0; - Pattern pattern = data.backgroundPattern; - if (pattern != null) { - data.gdipBrush = pattern.handle; - if ((data.style & SWT.MIRRORED) != 0) { - switch (Gdip.Brush_GetType(data.gdipBrush)) { - case Gdip.BrushTypeTextureFill: - int /*long*/ brush = Gdip.Brush_Clone(data.gdipBrush); - if (brush == 0) SWT.error(SWT.ERROR_NO_HANDLES); - Gdip.TextureBrush_ScaleTransform(brush, -1, 1, Gdip.MatrixOrderPrepend); - data.gdipBrush = data.gdipBgBrush = brush; - } - } - } else { - int background = data.background; - int rgb = ((background >> 16) & 0xFF) | (background & 0xFF00) | ((background & 0xFF) << 16); - int /*long*/ color = Gdip.Color_new(data.alpha << 24 | rgb); - if (color == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int /*long*/ brush = Gdip.SolidBrush_new(color); - if (brush == 0) SWT.error(SWT.ERROR_NO_HANDLES); - Gdip.Color_delete(color); - data.gdipBrush = data.gdipBgBrush = brush; - } - } - if ((state & FONT) != 0) { - Font font = data.font; - OS.SelectObject(handle, font.handle); - int /*long*/[] hFont = new int /*long*/[1]; - int /*long*/ gdipFont = createGdipFont(handle, font.handle, gdipGraphics, device.fontCollection, null, hFont); - if (hFont[0] != 0) { - OS.SelectObject(handle, hFont[0]); - if (data.hGDIFont != 0) OS.DeleteObject(data.hGDIFont); - data.hGDIFont = hFont[0]; - } - if (data.gdipFont != 0) Gdip.Font_delete(data.gdipFont); - data.gdipFont = gdipFont; - } - if ((state & DRAW_OFFSET) != 0) { - data.gdipXOffset = data.gdipYOffset = 0; - int /*long*/ matrix = Gdip.Matrix_new(1, 0, 0, 1, 0, 0); - PointF point = new PointF(); - point.X = point.Y = 1; - Gdip.Graphics_GetTransform(gdipGraphics, matrix); - Gdip.Matrix_TransformVectors(matrix, point, 1); - Gdip.Matrix_delete(matrix); - float scaling = point.X; - if (scaling < 0) scaling = -scaling; - float penWidth = data.lineWidth * scaling; - if (penWidth == 0 || ((int)penWidth % 2) == 1) { - data.gdipXOffset = 0.5f / scaling; - } - scaling = point.Y; - if (scaling < 0) scaling = -scaling; - penWidth = data.lineWidth * scaling; - if (penWidth == 0 || ((int)penWidth % 2) == 1) { - data.gdipYOffset = 0.5f / scaling; - } - } - return; - } - if ((state & (FOREGROUND | LINE_CAP | LINE_JOIN | LINE_STYLE | LINE_WIDTH)) != 0) { - int color = data.foreground; - int width = (int)data.lineWidth; - int[] dashes = null; - int lineStyle = OS.PS_SOLID; - switch (data.lineStyle) { - case SWT.LINE_SOLID: break; - case SWT.LINE_DASH: lineStyle = OS.PS_DASH; break; - case SWT.LINE_DOT: lineStyle = OS.PS_DOT; break; - case SWT.LINE_DASHDOT: lineStyle = OS.PS_DASHDOT; break; - case SWT.LINE_DASHDOTDOT: lineStyle = OS.PS_DASHDOTDOT; break; - case SWT.LINE_CUSTOM: { - if (data.lineDashes != null) { - lineStyle = OS.PS_USERSTYLE; - dashes = new int[data.lineDashes.length]; - for (int i = 0; i < dashes.length; i++) { - dashes[i] = (int)data.lineDashes[i]; - } - } - break; - } - } - if ((state & LINE_STYLE) != 0) { - OS.SetBkMode(handle, data.lineStyle == SWT.LINE_SOLID ? OS.OPAQUE : OS.TRANSPARENT); - } - int joinStyle = 0; - switch (data.lineJoin) { - case SWT.JOIN_MITER: joinStyle = OS.PS_JOIN_MITER; break; - case SWT.JOIN_ROUND: joinStyle = OS.PS_JOIN_ROUND; break; - case SWT.JOIN_BEVEL: joinStyle = OS.PS_JOIN_BEVEL; break; - } - int capStyle = 0; - switch (data.lineCap) { - case SWT.CAP_ROUND: capStyle = OS.PS_ENDCAP_ROUND; break; - case SWT.CAP_FLAT: capStyle = OS.PS_ENDCAP_FLAT; break; - case SWT.CAP_SQUARE: capStyle = OS.PS_ENDCAP_SQUARE;break; - } - int style = lineStyle | joinStyle | capStyle; - /* - * Feature in Windows. Windows does not honour line styles other then - * PS_SOLID for pens wider than 1 pixel created with CreatePen(). The fix - * is to use ExtCreatePen() instead. - */ - int /*long*/ newPen; - if (OS.IsWinCE || (width == 0 && lineStyle != OS.PS_USERSTYLE) || style == 0) { - newPen = OS.CreatePen(style & OS.PS_STYLE_MASK, width, color); - } else { - LOGBRUSH logBrush = new LOGBRUSH(); - logBrush.lbStyle = OS.BS_SOLID; - logBrush.lbColor = color; - /* Feature in Windows. PS_GEOMETRIC pens cannot have zero width. */ - newPen = OS.ExtCreatePen (style | OS.PS_GEOMETRIC, Math.max(1, width), logBrush, dashes != null ? dashes.length : 0, dashes); - } - OS.SelectObject(handle, newPen); - data.state |= PEN; - data.state &= ~NULL_PEN; - if (data.hPen != 0) OS.DeleteObject(data.hPen); - data.hPen = data.hOldPen = newPen; - } else if ((state & PEN) != 0) { - OS.SelectObject(handle, data.hOldPen); - data.state &= ~NULL_PEN; - } else if ((state & NULL_PEN) != 0) { - data.hOldPen = OS.SelectObject(handle, OS.GetStockObject(OS.NULL_PEN)); - data.state &= ~PEN; - } - if ((state & BACKGROUND) != 0) { - int /*long*/ newBrush = OS.CreateSolidBrush(data.background); - OS.SelectObject(handle, newBrush); - data.state |= BRUSH; - data.state &= ~NULL_BRUSH; - if (data.hBrush != 0) OS.DeleteObject(data.hBrush); - data.hOldBrush = data.hBrush = newBrush; - } else if ((state & BRUSH) != 0) { - OS.SelectObject(handle, data.hOldBrush); - data.state &= ~NULL_BRUSH; - } else if ((state & NULL_BRUSH) != 0) { - data.hOldBrush = OS.SelectObject(handle, OS.GetStockObject(OS.NULL_BRUSH)); - data.state &= ~BRUSH; - } - if ((state & BACKGROUND_TEXT) != 0) { - OS.SetBkColor(handle, data.background); - } - if ((state & FOREGROUND_TEXT) != 0) { - OS.SetTextColor(handle, data.foreground); - } - if ((state & FONT) != 0) { - Font font = data.font; - OS.SelectObject(handle, font.handle); - } -} - -/** - * 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); - - /* Copy the bitmap area */ - Rectangle rect = image.getBounds(); - int /*long*/ memHdc = OS.CreateCompatibleDC(handle); - int /*long*/ hOldBitmap = OS.SelectObject(memHdc, image.handle); - OS.BitBlt(memHdc, 0, 0, rect.width, rect.height, handle, x, y, OS.SRCCOPY); - OS.SelectObject(memHdc, hOldBitmap); - OS.DeleteDC(memHdc); -} - -/** - * 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); - - /* - * Feature in WinCE. The function WindowFromDC is not part of the - * WinCE SDK. The fix is to remember the HWND. - */ - int /*long*/ hwnd = data.hwnd; - if (hwnd == 0) { - OS.BitBlt(handle, destX, destY, width, height, handle, srcX, srcY, OS.SRCCOPY); - } else { - RECT lprcClip = null; - int /*long*/ hrgn = OS.CreateRectRgn(0, 0, 0, 0); - if (OS.GetClipRgn(handle, hrgn) == 1) { - lprcClip = new RECT(); - OS.GetRgnBox(hrgn, lprcClip); - } - OS.DeleteObject(hrgn); - RECT lprcScroll = new RECT(); - OS.SetRect(lprcScroll, srcX, srcY, srcX + width, srcY + height); - int flags = paint ? OS.SW_INVALIDATE | OS.SW_ERASE : 0; - int res = OS.ScrollWindowEx(hwnd, destX - srcX, destY - srcY, lprcScroll, lprcClip, 0, null, flags); - - /* - * Feature in WinCE. ScrollWindowEx does not accept combined - * vertical and horizontal scrolling. The fix is to do a - * BitBlt and invalidate the appropriate source area. - */ - if (res == 0 && OS.IsWinCE) { - OS.BitBlt(handle, destX, destY, width, height, handle, srcX, srcY, OS.SRCCOPY); - if (paint) { - int deltaX = destX - srcX, deltaY = destY - srcY; - boolean disjoint = (destX + width < srcX) || (srcX + width < destX) || (destY + height < srcY) || (srcY + height < destY); - if (disjoint) { - OS.InvalidateRect(hwnd, lprcScroll, true); - } else { - if (deltaX != 0) { - int newX = destX - deltaX; - if (deltaX < 0) newX = destX + width; - OS.SetRect(lprcScroll, newX, srcY, newX + Math.abs(deltaX), srcY + height); - OS.InvalidateRect(hwnd, lprcScroll, true); - } - if (deltaY != 0) { - int newY = destY - deltaY; - if (deltaY < 0) newY = destY + height; - OS.SetRect(lprcScroll, srcX, newY, srcX + width, newY + Math.abs(deltaY)); - OS.InvalidateRect(hwnd, lprcScroll, true); - } - } - } - } - } -} -static int /*long*/ createGdipFont(int /*long*/ hDC, int /*long*/ hFont, int /*long*/ graphics, int /*long*/ fontCollection, int /*long*/ [] outFamily, int /*long*/[] outFont) { - int /*long*/ font = Gdip.Font_new(hDC, hFont); - if (font == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int /*long*/ family = 0; - if (!Gdip.Font_IsAvailable(font)) { - Gdip.Font_delete(font); - LOGFONT logFont = OS.IsUnicode ? (LOGFONT)new LOGFONTW() : new LOGFONTA(); - OS.GetObject(hFont, LOGFONT.sizeof, logFont); - int size = Math.abs(logFont.lfHeight); - int style = Gdip.FontStyleRegular; - if (logFont.lfWeight == 700) style |= Gdip.FontStyleBold; - if (logFont.lfItalic != 0) style |= Gdip.FontStyleItalic; - char[] chars; - if (OS.IsUnicode) { - chars = ((LOGFONTW)logFont).lfFaceName; - } else { - chars = new char[OS.LF_FACESIZE]; - byte[] bytes = ((LOGFONTA)logFont).lfFaceName; - OS.MultiByteToWideChar (OS.CP_ACP, OS.MB_PRECOMPOSED, bytes, bytes.length, chars, chars.length); - } - int index = 0; - while (index < chars.length) { - if (chars [index] == 0) break; - index++; - } - String name = new String (chars, 0, index); - if (Compatibility.equalsIgnoreCase(name, "Courier")) { //$NON-NLS-1$ - name = "Courier New"; //$NON-NLS-1$ - } - char[] buffer = new char[name.length() + 1]; - name.getChars(0, name.length(), buffer, 0); - if (fontCollection != 0) { - family = Gdip.FontFamily_new(buffer, fontCollection); - if (!Gdip.FontFamily_IsAvailable(family)) { - Gdip.FontFamily_delete(family); - family = Gdip.FontFamily_new(buffer, 0); - if (!Gdip.FontFamily_IsAvailable(family)) { - Gdip.FontFamily_delete(family); - family = 0; - } - } - } - if (family != 0) { - font = Gdip.Font_new(family, size, style, Gdip.UnitPixel); - } else { - font = Gdip.Font_new(buffer, size, style, Gdip.UnitPixel, 0); - } - if (outFont != null && font != 0) { - int /*long*/ hHeap = OS.GetProcessHeap(); - int /*long*/ pLogFont = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, LOGFONTW.sizeof); - Gdip.Font_GetLogFontW(font, graphics, pLogFont); - outFont[0] = OS.CreateFontIndirectW(pLogFont); - OS.HeapFree(hHeap, 0, pLogFont); - } - } - if (outFamily != null && font != 0) { - if (family == 0) { - family = Gdip.FontFamily_new(); - Gdip.Font_GetFamily(font, family); - } - outFamily [0] = family; - } else { - if (family != 0) Gdip.FontFamily_delete(family); - } - if (font == 0) SWT.error(SWT.ERROR_NO_HANDLES); - return font; -} - -static void destroyGdipBrush(int /*long*/ brush) { - int type = Gdip.Brush_GetType(brush); - switch (type) { - case Gdip.BrushTypeSolidColor: - Gdip.SolidBrush_delete(brush); - break; - case Gdip.BrushTypeHatchFill: - Gdip.HatchBrush_delete(brush); - break; - case Gdip.BrushTypeLinearGradient: - Gdip.LinearGradientBrush_delete(brush); - break; - case Gdip.BrushTypeTextureFill: - Gdip.TextureBrush_delete(brush); - break; - } -} - -/** - * Disposes of the operating system resources associated with - * the graphics context. Applications must dispose of all GCs - * which they allocate. - * - * @exception SWTError <ul> - * <li>ERROR_THREAD_INVALID_ACCESS if not called from the thread that created the drawable</li> - * </ul> - */ -void destroy() { - boolean gdip = data.gdipGraphics != 0; - disposeGdip(); - if (gdip && (data.style & SWT.MIRRORED) != 0) { - OS.SetLayout(handle, OS.GetLayout(handle) | OS.LAYOUT_RTL); - } - - /* Select stock pen and brush objects and free resources */ - if (data.hPen != 0) { - OS.SelectObject(handle, OS.GetStockObject(OS.NULL_PEN)); - OS.DeleteObject(data.hPen); - data.hPen = 0; - } - if (data.hBrush != 0) { - OS.SelectObject(handle, OS.GetStockObject(OS.NULL_BRUSH)); - OS.DeleteObject(data.hBrush); - data.hBrush = 0; - } - - /* - * Put back the original bitmap into the device context. - * This will ensure that we have not left a bitmap - * selected in it when we delete the HDC. - */ - int /*long*/ hNullBitmap = data.hNullBitmap; - if (hNullBitmap != 0) { - OS.SelectObject(handle, hNullBitmap); - data.hNullBitmap = 0; - } - Image image = data.image; - if (image != null) image.memGC = null; - - /* - * Dispose the HDC. - */ - if (drawable != null) drawable.internal_dispose_GC(handle, data); - drawable = null; - handle = 0; - data.image = null; - data.ps = null; - data = null; -} - -void disposeGdip() { - if (data.gdipPen != 0) Gdip.Pen_delete(data.gdipPen); - if (data.gdipBgBrush != 0) destroyGdipBrush(data.gdipBgBrush); - if (data.gdipFgBrush != 0) destroyGdipBrush(data.gdipFgBrush); - if (data.gdipFont != 0) Gdip.Font_delete(data.gdipFont); - if (data.hGDIFont != 0) OS.DeleteObject(data.hGDIFont); - if (data.gdipGraphics != 0) Gdip.Graphics_delete(data.gdipGraphics); - data.gdipGraphics = data.gdipBrush = data.gdipBgBrush = data.gdipFgBrush = - data.gdipFont = data.gdipPen = data.hGDIFont = 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 (width < 0) { - x = x + width; - width = -width; - } - if (height < 0) { - y = y + height; - height = -height; - } - if (width == 0 || height == 0 || arcAngle == 0) return; - int /*long*/ gdipGraphics = data.gdipGraphics; - if (gdipGraphics != 0) { - Gdip.Graphics_TranslateTransform(gdipGraphics, data.gdipXOffset, data.gdipYOffset, Gdip.MatrixOrderPrepend); - if (width == height) { - Gdip.Graphics_DrawArc(gdipGraphics, data.gdipPen, x, y, width, height, -startAngle, -arcAngle); - } else { - int /*long*/ path = Gdip.GraphicsPath_new(Gdip.FillModeAlternate); - if (path == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int /*long*/ matrix = Gdip.Matrix_new(width, 0, 0, height, x, y); - if (matrix == 0) SWT.error(SWT.ERROR_NO_HANDLES); - Gdip.GraphicsPath_AddArc(path, 0, 0, 1, 1, -startAngle, -arcAngle); - Gdip.GraphicsPath_Transform(path, matrix); - Gdip.Graphics_DrawPath(gdipGraphics, data.gdipPen, path); - Gdip.Matrix_delete(matrix); - Gdip.GraphicsPath_delete(path); - } - Gdip.Graphics_TranslateTransform(gdipGraphics, -data.gdipXOffset, -data.gdipYOffset, Gdip.MatrixOrderPrepend); - return; - } - if ((data.style & SWT.MIRRORED) != 0) { - if (data.lineWidth != 0 && data.lineWidth % 2 == 0) x--; - } - /* - * Feature in WinCE. The function Arc is not present in the - * WinCE SDK. The fix is to emulate arc drawing by using - * Polyline. - */ - if (OS.IsWinCE) { - /* compute arc with a simple linear interpolation */ - if (arcAngle < 0) { - startAngle += arcAngle; - arcAngle = -arcAngle; - } - if (arcAngle > 360) arcAngle = 360; - int[] points = new int[(arcAngle + 1) * 2]; - int cteX = 2 * x + width; - int cteY = 2 * y + height; - int index = 0; - for (int i = 0; i <= arcAngle; i++) { - points[index++] = (Compatibility.cos(startAngle + i, width) + cteX) >> 1; - points[index++] = (cteY - Compatibility.sin(startAngle + i, height)) >> 1; - } - OS.Polyline(handle, points, points.length / 2); - } else { - int x1, y1, x2, y2,tmp; - boolean isNegative; - if (arcAngle >= 360 || arcAngle <= -360) { - x1 = x2 = x + width; - y1 = y2 = y + height / 2; - } else { - isNegative = arcAngle < 0; - - arcAngle = arcAngle + startAngle; - if (isNegative) { - // swap angles - tmp = startAngle; - startAngle = arcAngle; - arcAngle = tmp; - } - x1 = Compatibility.cos(startAngle, width) + x + width/2; - y1 = -1 * Compatibility.sin(startAngle, height) + y + height/2; - - x2 = Compatibility.cos(arcAngle, width) + x + width/2; - y2 = -1 * Compatibility.sin(arcAngle, height) + y + height/2; - } - OS.Arc(handle, x, y, x + width + 1, y + height + 1, x1, y1, x2, y2); - } -} - -/** - * 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.uiState & OS.UISF_HIDEFOCUS) != 0) return; - data.focusDrawn = true; - int /*long*/ hdc = handle; - int state = 0; - int /*long*/ gdipGraphics = data.gdipGraphics; - if (gdipGraphics != 0) { - int /*long*/ clipRgn = 0; - Gdip.Graphics_SetPixelOffsetMode(gdipGraphics, Gdip.PixelOffsetModeNone); - int /*long*/ rgn = Gdip.Region_new(); - if (rgn == 0) SWT.error(SWT.ERROR_NO_HANDLES); - Gdip.Graphics_GetClip(gdipGraphics, rgn); - if (!Gdip.Region_IsInfinite(rgn, gdipGraphics)) { - clipRgn = Gdip.Region_GetHRGN(rgn, gdipGraphics); - } - Gdip.Region_delete(rgn); - Gdip.Graphics_SetPixelOffsetMode(gdipGraphics, Gdip.PixelOffsetModeHalf); - float[] lpXform = null; - int /*long*/ matrix = Gdip.Matrix_new(1, 0, 0, 1, 0, 0); - if (matrix == 0) SWT.error(SWT.ERROR_NO_HANDLES); - Gdip.Graphics_GetTransform(gdipGraphics, matrix); - if (!Gdip.Matrix_IsIdentity(matrix)) { - lpXform = new float[6]; - Gdip.Matrix_GetElements(matrix, lpXform); - } - Gdip.Matrix_delete(matrix); - hdc = Gdip.Graphics_GetHDC(gdipGraphics); - state = OS.SaveDC(hdc); - if (lpXform != null) { - OS.SetGraphicsMode(hdc, OS.GM_ADVANCED); - OS.SetWorldTransform(hdc, lpXform); - } - if (clipRgn != 0) { - OS.SelectClipRgn(hdc, clipRgn); - OS.DeleteObject(clipRgn); - } - } - OS.SetBkColor(hdc, 0xFFFFFF); - OS.SetTextColor(hdc, 0x000000); - RECT rect = new RECT(); - OS.SetRect(rect, x, y, x + width, y + height); - OS.DrawFocusRect(hdc, rect); - if (gdipGraphics != 0) { - OS.RestoreDC(hdc, state); - Gdip.Graphics_ReleaseHDC(gdipGraphics, hdc); - } else { - data.state &= ~(BACKGROUND_TEXT | FOREGROUND_TEXT); - } -} - -/** - * 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.gdipGraphics != 0) { - //TODO - cache bitmap - int /*long*/ [] gdipImage = srcImage.createGdipImage(); - int /*long*/ img = gdipImage[0]; - int imgWidth = Gdip.Image_GetWidth(img); - int imgHeight = Gdip.Image_GetHeight(img); - if (simple) { - srcWidth = destWidth = imgWidth; - srcHeight = destHeight = imgHeight; - } else { - if (srcX + srcWidth > imgWidth || srcY + srcHeight > imgHeight) { - SWT.error (SWT.ERROR_INVALID_ARGUMENT); - } - simple = srcX == 0 && srcY == 0 && - srcWidth == destWidth && destWidth == imgWidth && - srcHeight == destHeight && destHeight == imgHeight; - } - Rect rect = new Rect(); - rect.X = destX; - rect.Y = destY; - rect.Width = destWidth; - rect.Height = destHeight; - /* - * Note that if the wrap mode is not WrapModeTileFlipXY, the scaled image - * is translucent around the borders. - */ - int /*long*/ attrib = Gdip.ImageAttributes_new(); - Gdip.ImageAttributes_SetWrapMode(attrib, Gdip.WrapModeTileFlipXY); - if (data.alpha != 0xFF) { - float[] matrix = new float[]{ - 1,0,0,0,0, - 0,1,0,0,0, - 0,0,1,0,0, - 0,0,0,data.alpha / (float)0xFF,0, - 0,0,0,0,1, - }; - Gdip.ImageAttributes_SetColorMatrix(attrib, matrix, Gdip.ColorMatrixFlagsDefault, Gdip.ColorAdjustTypeBitmap); - } - int gstate = 0; - if ((data.style & SWT.MIRRORED) != 0) { - gstate = Gdip.Graphics_Save(data.gdipGraphics); - Gdip.Graphics_ScaleTransform(data.gdipGraphics, -1, 1, Gdip.MatrixOrderPrepend); - Gdip.Graphics_TranslateTransform(data.gdipGraphics, - 2 * destX - destWidth, 0, Gdip.MatrixOrderPrepend); - } - Gdip.Graphics_DrawImage(data.gdipGraphics, img, rect, srcX, srcY, srcWidth, srcHeight, Gdip.UnitPixel, attrib, 0, 0); - if ((data.style & SWT.MIRRORED) != 0) { - Gdip.Graphics_Restore(data.gdipGraphics, gstate); - } - Gdip.ImageAttributes_delete(attrib); - Gdip.Bitmap_delete(img); - if (gdipImage[1] != 0) { - int /*long*/ hHeap = OS.GetProcessHeap (); - OS.HeapFree(hHeap, 0, gdipImage[1]); - } - return; - } - switch (srcImage.type) { - case SWT.BITMAP: - drawBitmap(srcImage, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple); - break; - case SWT.ICON: - drawIcon(srcImage, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple); - break; - } -} - -void drawIcon(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple) { - int technology = OS.GetDeviceCaps(handle, OS.TECHNOLOGY); - - boolean drawIcon = true; - int flags = OS.DI_NORMAL; - int offsetX = 0, offsetY = 0; - if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION(5, 1)) { - if ((OS.GetLayout(handle) & OS.LAYOUT_RTL) != 0) { - flags |= OS.DI_NOMIRROR; - /* - * Bug in Windows. For some reason, DrawIconEx() does not take - * into account the window origin when the DI_NOMIRROR and - * LAYOUT_RTL are set. The fix is to set the window origin to - * (0, 0) and offset the drawing ourselves. - */ - POINT pt = new POINT(); - OS.GetWindowOrgEx(handle, pt); - offsetX = pt.x; - offsetY = pt.y; - } - } else { - if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION(4, 10)) { - drawIcon = (OS.GetLayout(handle) & OS.LAYOUT_RTL) == 0; - } - } - - /* Simple case: no stretching, entire icon */ - if (simple && technology != OS.DT_RASPRINTER && drawIcon) { - if (offsetX != 0 || offsetY != 0) OS.SetWindowOrgEx(handle, 0, 0, null); - OS.DrawIconEx(handle, destX - offsetX, destY - offsetY, srcImage.handle, 0, 0, 0, 0, flags); - if (offsetX != 0 || offsetY != 0) OS.SetWindowOrgEx(handle, offsetX, offsetY, null); - return; - } - - /* Get the icon info */ - ICONINFO srcIconInfo = new ICONINFO(); - if (OS.IsWinCE) { - Image.GetIconInfo(srcImage, srcIconInfo); - } else { - OS.GetIconInfo(srcImage.handle, srcIconInfo); - } - - /* Get the icon width and height */ - int /*long*/ hBitmap = srcIconInfo.hbmColor; - if (hBitmap == 0) hBitmap = srcIconInfo.hbmMask; - BITMAP bm = new BITMAP(); - OS.GetObject(hBitmap, BITMAP.sizeof, bm); - int iconWidth = bm.bmWidth, iconHeight = bm.bmHeight; - if (hBitmap == srcIconInfo.hbmMask) iconHeight /= 2; - - if (simple) { - srcWidth = destWidth = iconWidth; - srcHeight = destHeight = iconHeight; - } - - /* Draw the icon */ - boolean failed = srcX + srcWidth > iconWidth || srcY + srcHeight > iconHeight; - if (!failed) { - simple = srcX == 0 && srcY == 0 && - srcWidth == destWidth && srcHeight == destHeight && - srcWidth == iconWidth && srcHeight == iconHeight; - if (!drawIcon) { - drawBitmapMask(srcImage, srcIconInfo.hbmColor, srcIconInfo.hbmMask, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple, iconWidth, iconHeight, false); - } else if (simple && technology != OS.DT_RASPRINTER) { - /* Simple case: no stretching, entire icon */ - if (offsetX != 0 || offsetY != 0) OS.SetWindowOrgEx(handle, 0, 0, null); - OS.DrawIconEx(handle, destX - offsetX, destY - offsetY, srcImage.handle, 0, 0, 0, 0, flags); - if (offsetX != 0 || offsetY != 0) OS.SetWindowOrgEx(handle, offsetX, offsetY, null); - } else { - /* Create the icon info and HDC's */ - ICONINFO newIconInfo = new ICONINFO(); - newIconInfo.fIcon = true; - int /*long*/ srcHdc = OS.CreateCompatibleDC(handle); - int /*long*/ dstHdc = OS.CreateCompatibleDC(handle); - - /* Blt the color bitmap */ - int srcColorY = srcY; - int /*long*/ srcColor = srcIconInfo.hbmColor; - if (srcColor == 0) { - srcColor = srcIconInfo.hbmMask; - srcColorY += iconHeight; - } - int /*long*/ oldSrcBitmap = OS.SelectObject(srcHdc, srcColor); - newIconInfo.hbmColor = OS.CreateCompatibleBitmap(srcHdc, destWidth, destHeight); - if (newIconInfo.hbmColor == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int /*long*/ oldDestBitmap = OS.SelectObject(dstHdc, newIconInfo.hbmColor); - boolean stretch = !simple && (srcWidth != destWidth || srcHeight != destHeight); - if (stretch) { - if (!OS.IsWinCE) OS.SetStretchBltMode(dstHdc, OS.COLORONCOLOR); - OS.StretchBlt(dstHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcColorY, srcWidth, srcHeight, OS.SRCCOPY); - } else { - OS.BitBlt(dstHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcColorY, OS.SRCCOPY); - } - - /* Blt the mask bitmap */ - OS.SelectObject(srcHdc, srcIconInfo.hbmMask); - newIconInfo.hbmMask = OS.CreateBitmap(destWidth, destHeight, 1, 1, null); - if (newIconInfo.hbmMask == 0) SWT.error(SWT.ERROR_NO_HANDLES); - OS.SelectObject(dstHdc, newIconInfo.hbmMask); - if (stretch) { - OS.StretchBlt(dstHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, OS.SRCCOPY); - } else { - OS.BitBlt(dstHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcY, OS.SRCCOPY); - } - - if (technology == OS.DT_RASPRINTER) { - OS.SelectObject(srcHdc, newIconInfo.hbmColor); - OS.SelectObject(dstHdc, newIconInfo.hbmMask); - drawBitmapTransparentByClipping(srcHdc, dstHdc, 0, 0, destWidth, destHeight, destX, destY, destWidth, destHeight, true, destWidth, destHeight); - OS.SelectObject(srcHdc, oldSrcBitmap); - OS.SelectObject(dstHdc, oldDestBitmap); - } else { - OS.SelectObject(srcHdc, oldSrcBitmap); - OS.SelectObject(dstHdc, oldDestBitmap); - int /*long*/ hIcon = OS.CreateIconIndirect(newIconInfo); - if (hIcon == 0) SWT.error(SWT.ERROR_NO_HANDLES); - if (offsetX != 0 || offsetY != 0) OS.SetWindowOrgEx(handle, 0, 0, null); - OS.DrawIconEx(handle, destX - offsetX, destY - offsetY, hIcon, destWidth, destHeight, 0, 0, flags); - if (offsetX != 0 || offsetY != 0) OS.SetWindowOrgEx(handle, offsetX, offsetY, null); - OS.DestroyIcon(hIcon); - } - - /* Destroy the new icon src and mask and hdc's*/ - OS.DeleteObject(newIconInfo.hbmMask); - OS.DeleteObject(newIconInfo.hbmColor); - OS.DeleteDC(dstHdc); - OS.DeleteDC(srcHdc); - } - } - - /* Free icon info */ - OS.DeleteObject(srcIconInfo.hbmMask); - if (srcIconInfo.hbmColor != 0) { - OS.DeleteObject(srcIconInfo.hbmColor); - } - - if (failed) SWT.error(SWT.ERROR_INVALID_ARGUMENT); -} - -void drawBitmap(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple) { - BITMAP bm = new BITMAP(); - OS.GetObject(srcImage.handle, BITMAP.sizeof, bm); - int imgWidth = bm.bmWidth; - int imgHeight = bm.bmHeight; - if (simple) { - srcWidth = destWidth = imgWidth; - srcHeight = destHeight = imgHeight; - } else { - if (srcX + srcWidth > imgWidth || srcY + srcHeight > imgHeight) { - SWT.error (SWT.ERROR_INVALID_ARGUMENT); - } - simple = srcX == 0 && srcY == 0 && - srcWidth == destWidth && destWidth == imgWidth && - srcHeight == destHeight && destHeight == imgHeight; - } - boolean mustRestore = false; - GC memGC = srcImage.memGC; - if (memGC != null && !memGC.isDisposed()) { - memGC.flush(); - mustRestore = true; - GCData data = memGC.data; - if (data.hNullBitmap != 0) { - OS.SelectObject(memGC.handle, data.hNullBitmap); - data.hNullBitmap = 0; - } - } - if (srcImage.alpha != -1 || srcImage.alphaData != null) { - drawBitmapAlpha(srcImage, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple, bm, imgWidth, imgHeight); - } else if (srcImage.transparentPixel != -1) { - drawBitmapTransparent(srcImage, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple, bm, imgWidth, imgHeight); - } else { - drawBitmap(srcImage, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple, bm, imgWidth, imgHeight); - } - if (mustRestore) { - int /*long*/ hOldBitmap = OS.SelectObject(memGC.handle, srcImage.handle); - memGC.data.hNullBitmap = hOldBitmap; - } -} - -void drawBitmapAlpha(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple, BITMAP bm, int imgWidth, int imgHeight) { - /* Simple cases */ - if (srcImage.alpha == 0) return; - if (srcImage.alpha == 255) { - drawBitmap(srcImage, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple, bm, imgWidth, imgHeight); - return; - } - - if (OS.IsWinNT && OS.WIN32_VERSION >= OS.VERSION(4, 10)) { - BLENDFUNCTION blend = new BLENDFUNCTION(); - blend.BlendOp = OS.AC_SRC_OVER; - int /*long*/ srcHdc = OS.CreateCompatibleDC(handle); - int /*long*/ oldSrcBitmap = OS.SelectObject(srcHdc, srcImage.handle); - if (srcImage.alpha != -1) { - blend.SourceConstantAlpha = (byte)srcImage.alpha; - OS.AlphaBlend(handle, destX, destY, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, blend); - } else { - int /*long*/ memDib = Image.createDIB(srcWidth, srcHeight, 32); - if (memDib == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int /*long*/ memHdc = OS.CreateCompatibleDC(handle); - int /*long*/ oldMemBitmap = OS.SelectObject(memHdc, memDib); - BITMAP dibBM = new BITMAP(); - OS.GetObject(memDib, BITMAP.sizeof, dibBM); - OS.BitBlt(memHdc, 0, 0, srcWidth, srcHeight, srcHdc, srcX, srcY, OS.SRCCOPY); - byte[] srcData = new byte[dibBM.bmWidthBytes * dibBM.bmHeight]; - OS.MoveMemory(srcData, dibBM.bmBits, srcData.length); - final int apinc = imgWidth - srcWidth; - int ap = srcY * imgWidth + srcX, sp = 0; - byte[] alphaData = srcImage.alphaData; - for (int y = 0; y < srcHeight; ++y) { - for (int x = 0; x < srcWidth; ++x) { - int alpha = alphaData[ap++] & 0xff; - int r = ((srcData[sp + 0] & 0xFF) * alpha) + 128; - r = (r + (r >> 8)) >> 8; - int g = ((srcData[sp + 1] & 0xFF) * alpha) + 128; - g = (g + (g >> 8)) >> 8; - int b = ((srcData[sp + 2] & 0xFF) * alpha) + 128; - b = (b + (b >> 8)) >> 8; - srcData[sp+0] = (byte)r; - srcData[sp+1] = (byte)g; - srcData[sp+2] = (byte)b; - srcData[sp+3] = (byte)alpha; - sp += 4; - } - ap += apinc; - } - OS.MoveMemory(dibBM.bmBits, srcData, srcData.length); - blend.SourceConstantAlpha = (byte)0xff; - blend.AlphaFormat = OS.AC_SRC_ALPHA; - OS.AlphaBlend(handle, destX, destY, destWidth, destHeight, memHdc, 0, 0, srcWidth, srcHeight, blend); - OS.SelectObject(memHdc, oldMemBitmap); - OS.DeleteDC(memHdc); - OS.DeleteObject(memDib); - } - OS.SelectObject(srcHdc, oldSrcBitmap); - OS.DeleteDC(srcHdc); - return; - } - - /* Check clipping */ - Rectangle rect = getClipping(); - rect = rect.intersection(new Rectangle(destX, destY, destWidth, destHeight)); - if (rect.isEmpty()) return; - - /* - * Optimization. Recalculate src and dest rectangles so that - * only the clipping area is drawn. - */ - int sx1 = srcX + (((rect.x - destX) * srcWidth) / destWidth); - int sx2 = srcX + ((((rect.x + rect.width) - destX) * srcWidth) / destWidth); - int sy1 = srcY + (((rect.y - destY) * srcHeight) / destHeight); - int sy2 = srcY + ((((rect.y + rect.height) - destY) * srcHeight) / destHeight); - destX = rect.x; - destY = rect.y; - destWidth = rect.width; - destHeight = rect.height; - srcX = sx1; - srcY = sy1; - srcWidth = Math.max(1, sx2 - sx1); - srcHeight = Math.max(1, sy2 - sy1); - - /* Create resources */ - int /*long*/ srcHdc = OS.CreateCompatibleDC(handle); - int /*long*/ oldSrcBitmap = OS.SelectObject(srcHdc, srcImage.handle); - int /*long*/ memHdc = OS.CreateCompatibleDC(handle); - int /*long*/ memDib = Image.createDIB(Math.max(srcWidth, destWidth), Math.max(srcHeight, destHeight), 32); - if (memDib == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int /*long*/ oldMemBitmap = OS.SelectObject(memHdc, memDib); - - BITMAP dibBM = new BITMAP(); - OS.GetObject(memDib, BITMAP.sizeof, dibBM); - int sizeInBytes = dibBM.bmWidthBytes * dibBM.bmHeight; - - /* Get the background pixels */ - OS.BitBlt(memHdc, 0, 0, destWidth, destHeight, handle, destX, destY, OS.SRCCOPY); - byte[] destData = new byte[sizeInBytes]; - OS.MoveMemory(destData, dibBM.bmBits, sizeInBytes); - - /* Get the foreground pixels */ - OS.BitBlt(memHdc, 0, 0, srcWidth, srcHeight, srcHdc, srcX, srcY, OS.SRCCOPY); - byte[] srcData = new byte[sizeInBytes]; - OS.MoveMemory(srcData, dibBM.bmBits, sizeInBytes); - - /* Merge the alpha channel in place */ - int alpha = srcImage.alpha; - final boolean hasAlphaChannel = (srcImage.alpha == -1); - if (hasAlphaChannel) { - final int apinc = imgWidth - srcWidth; - final int spinc = dibBM.bmWidthBytes - srcWidth * 4; - int ap = srcY * imgWidth + srcX, sp = 3; - byte[] alphaData = srcImage.alphaData; - for (int y = 0; y < srcHeight; ++y) { - for (int x = 0; x < srcWidth; ++x) { - srcData[sp] = alphaData[ap++]; - sp += 4; - } - ap += apinc; - sp += spinc; - } - } - - /* Scale the foreground pixels with alpha */ - OS.MoveMemory(dibBM.bmBits, srcData, sizeInBytes); - /* - * Bug in WinCE and Win98. StretchBlt does not correctly stretch when - * the source and destination HDCs are the same. The workaround is to - * stretch to a temporary HDC and blit back into the original HDC. - * Note that on WinCE StretchBlt correctly compresses the image when the - * source and destination HDCs are the same. - */ - if ((OS.IsWinCE && (destWidth > srcWidth || destHeight > srcHeight)) || (!OS.IsWinNT && !OS.IsWinCE)) { - int /*long*/ tempHdc = OS.CreateCompatibleDC(handle); - int /*long*/ tempDib = Image.createDIB(destWidth, destHeight, 32); - if (tempDib == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int /*long*/ oldTempBitmap = OS.SelectObject(tempHdc, tempDib); - if (!simple && (srcWidth != destWidth || srcHeight != destHeight)) { - if (!OS.IsWinCE) OS.SetStretchBltMode(memHdc, OS.COLORONCOLOR); - OS.StretchBlt(tempHdc, 0, 0, destWidth, destHeight, memHdc, 0, 0, srcWidth, srcHeight, OS.SRCCOPY); - } else { - OS.BitBlt(tempHdc, 0, 0, destWidth, destHeight, memHdc, 0, 0, OS.SRCCOPY); - } - OS.BitBlt(memHdc, 0, 0, destWidth, destHeight, tempHdc, 0, 0, OS.SRCCOPY); - OS.SelectObject(tempHdc, oldTempBitmap); - OS.DeleteObject(tempDib); - OS.DeleteDC(tempHdc); - } else { - if (!simple && (srcWidth != destWidth || srcHeight != destHeight)) { - if (!OS.IsWinCE) OS.SetStretchBltMode(memHdc, OS.COLORONCOLOR); - OS.StretchBlt(memHdc, 0, 0, destWidth, destHeight, memHdc, 0, 0, srcWidth, srcHeight, OS.SRCCOPY); - } else { - OS.BitBlt(memHdc, 0, 0, destWidth, destHeight, memHdc, 0, 0, OS.SRCCOPY); - } - } - OS.MoveMemory(srcData, dibBM.bmBits, sizeInBytes); - - /* Compose the pixels */ - final int dpinc = dibBM.bmWidthBytes - destWidth * 4; - int dp = 0; - for (int y = 0; y < destHeight; ++y) { - for (int x = 0; x < destWidth; ++x) { - if (hasAlphaChannel) alpha = srcData[dp + 3] & 0xff; - destData[dp] += ((srcData[dp] & 0xff) - (destData[dp] & 0xff)) * alpha / 255; - destData[dp + 1] += ((srcData[dp + 1] & 0xff) - (destData[dp + 1] & 0xff)) * alpha / 255; - destData[dp + 2] += ((srcData[dp + 2] & 0xff) - (destData[dp + 2] & 0xff)) * alpha / 255; - dp += 4; - } - dp += dpinc; - } - - /* Draw the composed pixels */ - OS.MoveMemory(dibBM.bmBits, destData, sizeInBytes); - OS.BitBlt(handle, destX, destY, destWidth, destHeight, memHdc, 0, 0, OS.SRCCOPY); - - /* Free resources */ - OS.SelectObject(memHdc, oldMemBitmap); - OS.DeleteDC(memHdc); - OS.DeleteObject(memDib); - OS.SelectObject(srcHdc, oldSrcBitmap); - OS.DeleteDC(srcHdc); -} - -void drawBitmapTransparentByClipping(int /*long*/ srcHdc, int /*long*/ maskHdc, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple, int imgWidth, int imgHeight) { - /* Create a clipping region from the mask */ - int /*long*/ rgn = OS.CreateRectRgn(0, 0, 0, 0); - for (int y=0; y<imgHeight; y++) { - for (int x=0; x<imgWidth; x++) { - if (OS.GetPixel(maskHdc, x, y) == 0) { - int /*long*/ tempRgn = OS.CreateRectRgn(x, y, x+1, y+1); - OS.CombineRgn(rgn, rgn, tempRgn, OS.RGN_OR); - OS.DeleteObject(tempRgn); - } - } - } - /* Stretch the clipping mask if needed */ - if (destWidth != srcWidth || destHeight != srcHeight) { - int nBytes = OS.GetRegionData (rgn, 0, null); - int[] lpRgnData = new int[nBytes / 4]; - OS.GetRegionData (rgn, nBytes, lpRgnData); - float[] lpXform = new float[] {(float)destWidth/srcWidth, 0, 0, (float)destHeight/srcHeight, 0, 0}; - int /*long*/ tmpRgn = OS.ExtCreateRegion(lpXform, nBytes, lpRgnData); - OS.DeleteObject(rgn); - rgn = tmpRgn; - } - OS.OffsetRgn(rgn, destX, destY); - int /*long*/ clip = OS.CreateRectRgn(0, 0, 0, 0); - int result = OS.GetClipRgn(handle, clip); - if (result == 1) OS.CombineRgn(rgn, rgn, clip, OS.RGN_AND); - OS.SelectClipRgn(handle, rgn); - int rop2 = 0; - if (!OS.IsWinCE) { - rop2 = OS.GetROP2(handle); - } else { - rop2 = OS.SetROP2 (handle, OS.R2_COPYPEN); - OS.SetROP2 (handle, rop2); - } - int dwRop = rop2 == OS.R2_XORPEN ? OS.SRCINVERT : OS.SRCCOPY; - if (!simple && (srcWidth != destWidth || srcHeight != destHeight)) { - int mode = 0; - if (!OS.IsWinCE) mode = OS.SetStretchBltMode(handle, OS.COLORONCOLOR); - OS.StretchBlt(handle, destX, destY, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, dwRop); - if (!OS.IsWinCE) OS.SetStretchBltMode(handle, mode); - } else { - OS.BitBlt(handle, destX, destY, destWidth, destHeight, srcHdc, srcX, srcY, dwRop); - } - OS.SelectClipRgn(handle, result == 1 ? clip : 0); - OS.DeleteObject(clip); - OS.DeleteObject(rgn); -} - -void drawBitmapMask(Image srcImage, int /*long*/ srcColor, int /*long*/ srcMask, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple, int imgWidth, int imgHeight, boolean offscreen) { - int srcColorY = srcY; - if (srcColor == 0) { - srcColor = srcMask; - srcColorY += imgHeight; - } - int /*long*/ srcHdc = OS.CreateCompatibleDC(handle); - int /*long*/ oldSrcBitmap = OS.SelectObject(srcHdc, srcColor); - int /*long*/ destHdc = handle; - int x = destX, y = destY; - int /*long*/ tempHdc = 0, tempBitmap = 0, oldTempBitmap = 0; - int oldBkColor = 0, oldTextColor = 0; - if (offscreen) { - tempHdc = OS.CreateCompatibleDC(handle); - tempBitmap = OS.CreateCompatibleBitmap(handle, destWidth, destHeight); - oldTempBitmap = OS.SelectObject(tempHdc, tempBitmap); - OS.BitBlt(tempHdc, 0, 0, destWidth, destHeight, handle, destX, destY, OS.SRCCOPY); - destHdc = tempHdc; - x = y = 0; - } else { - oldBkColor = OS.SetBkColor(handle, 0xFFFFFF); - oldTextColor = OS.SetTextColor(handle, 0); - } - if (!simple && (srcWidth != destWidth || srcHeight != destHeight)) { - int mode = 0; - if (!OS.IsWinCE) mode = OS.SetStretchBltMode(handle, OS.COLORONCOLOR); - OS.StretchBlt(destHdc, x, y, destWidth, destHeight, srcHdc, srcX, srcColorY, srcWidth, srcHeight, OS.SRCINVERT); - OS.SelectObject(srcHdc, srcMask); - OS.StretchBlt(destHdc, x, y, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, OS.SRCAND); - OS.SelectObject(srcHdc, srcColor); - OS.StretchBlt(destHdc, x, y, destWidth, destHeight, srcHdc, srcX, srcColorY, srcWidth, srcHeight, OS.SRCINVERT); - if (!OS.IsWinCE) OS.SetStretchBltMode(handle, mode); - } else { - OS.BitBlt(destHdc, x, y, destWidth, destHeight, srcHdc, srcX, srcColorY, OS.SRCINVERT); - OS.SetTextColor(destHdc, 0); - OS.SelectObject(srcHdc, srcMask); - OS.BitBlt(destHdc, x, y, destWidth, destHeight, srcHdc, srcX, srcY, OS.SRCAND); - OS.SelectObject(srcHdc, srcColor); - OS.BitBlt(destHdc, x, y, destWidth, destHeight, srcHdc, srcX, srcColorY, OS.SRCINVERT); - } - if (offscreen) { - OS.BitBlt(handle, destX, destY, destWidth, destHeight, tempHdc, 0, 0, OS.SRCCOPY); - OS.SelectObject(tempHdc, oldTempBitmap); - OS.DeleteDC(tempHdc); - OS.DeleteObject(tempBitmap); - } else { - OS.SetBkColor(handle, oldBkColor); - OS.SetTextColor(handle, oldTextColor); - } - OS.SelectObject(srcHdc, oldSrcBitmap); - OS.DeleteDC(srcHdc); -} - -void drawBitmapTransparent(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple, BITMAP bm, int imgWidth, int imgHeight) { - - /* Find the RGB values for the transparent pixel. */ - boolean isDib = bm.bmBits != 0; - int /*long*/ hBitmap = srcImage.handle; - int /*long*/ srcHdc = OS.CreateCompatibleDC(handle); - int /*long*/ oldSrcBitmap = OS.SelectObject(srcHdc, hBitmap); - byte[] originalColors = null; - int transparentColor = srcImage.transparentColor; - if (transparentColor == -1) { - int transBlue = 0, transGreen = 0, transRed = 0; - boolean fixPalette = false; - if (bm.bmBitsPixel <= 8) { - if (isDib) { - /* Palette-based DIBSECTION */ - if (OS.IsWinCE) { - byte[] pBits = new byte[1]; - OS.MoveMemory(pBits, bm.bmBits, 1); - byte oldValue = pBits[0]; - int mask = (0xFF << (8 - bm.bmBitsPixel)) & 0x00FF; - pBits[0] = (byte)((srcImage.transparentPixel << (8 - bm.bmBitsPixel)) | (pBits[0] & ~mask)); - OS.MoveMemory(bm.bmBits, pBits, 1); - int color = OS.GetPixel(srcHdc, 0, 0); - pBits[0] = oldValue; - OS.MoveMemory(bm.bmBits, pBits, 1); - transBlue = (color & 0xFF0000) >> 16; - transGreen = (color & 0xFF00) >> 8; - transRed = color & 0xFF; - } else { - int maxColors = 1 << bm.bmBitsPixel; - byte[] oldColors = new byte[maxColors * 4]; - OS.GetDIBColorTable(srcHdc, 0, maxColors, oldColors); - int offset = srcImage.transparentPixel * 4; - for (int i = 0; i < oldColors.length; i += 4) { - if (i != offset) { - if (oldColors[offset] == oldColors[i] && oldColors[offset+1] == oldColors[i+1] && oldColors[offset+2] == oldColors[i+2]) { - fixPalette = true; - break; - } - } - } - if (fixPalette) { - byte[] newColors = new byte[oldColors.length]; - transRed = transGreen = transBlue = 0xff; - newColors[offset] = (byte)transBlue; - newColors[offset+1] = (byte)transGreen; - newColors[offset+2] = (byte)transRed; - OS.SetDIBColorTable(srcHdc, 0, maxColors, newColors); - originalColors = oldColors; - } else { - transBlue = oldColors[offset] & 0xFF; - transGreen = oldColors[offset+1] & 0xFF; - transRed = oldColors[offset+2] & 0xFF; - } - } - } else { - /* Palette-based bitmap */ - int numColors = 1 << bm.bmBitsPixel; - /* Set the few fields necessary to get the RGB data out */ - BITMAPINFOHEADER bmiHeader = new BITMAPINFOHEADER(); - bmiHeader.biSize = BITMAPINFOHEADER.sizeof; - bmiHeader.biPlanes = bm.bmPlanes; - bmiHeader.biBitCount = bm.bmBitsPixel; - byte[] bmi = new byte[BITMAPINFOHEADER.sizeof + numColors * 4]; - OS.MoveMemory(bmi, bmiHeader, BITMAPINFOHEADER.sizeof); - if (OS.IsWinCE) SWT.error(SWT.ERROR_NOT_IMPLEMENTED); - OS.GetDIBits(srcHdc, srcImage.handle, 0, 0, 0, bmi, OS.DIB_RGB_COLORS); - int offset = BITMAPINFOHEADER.sizeof + 4 * srcImage.transparentPixel; - transRed = bmi[offset + 2] & 0xFF; - transGreen = bmi[offset + 1] & 0xFF; - transBlue = bmi[offset] & 0xFF; - } - } else { - /* Direct color image */ - int pixel = srcImage.transparentPixel; - switch (bm.bmBitsPixel) { - case 16: - transBlue = (pixel & 0x1F) << 3; - transGreen = (pixel & 0x3E0) >> 2; - transRed = (pixel & 0x7C00) >> 7; - break; - case 24: - transBlue = (pixel & 0xFF0000) >> 16; - transGreen = (pixel & 0xFF00) >> 8; - transRed = pixel & 0xFF; - break; - case 32: - transBlue = (pixel & 0xFF000000) >>> 24; - transGreen = (pixel & 0xFF0000) >> 16; - transRed = (pixel & 0xFF00) >> 8; - break; - } - } - transparentColor = transBlue << 16 | transGreen << 8 | transRed; - if (!fixPalette) srcImage.transparentColor = transparentColor; - } - - if (OS.IsWinCE) { - /* - * Note in WinCE. TransparentImage uses the first entry of a palette - * based image when there are multiple entries that have the same - * transparent color. - */ - OS.TransparentImage(handle, destX, destY, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, transparentColor); - } else if (originalColors == null && OS.IsWinNT && OS.WIN32_VERSION >= OS.VERSION(4, 10)) { - int mode = OS.SetStretchBltMode(handle, OS.COLORONCOLOR); - OS.TransparentBlt(handle, destX, destY, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, transparentColor); - OS.SetStretchBltMode(handle, mode); - } else { - /* Create the mask for the source image */ - int /*long*/ maskHdc = OS.CreateCompatibleDC(handle); - int /*long*/ maskBitmap = OS.CreateBitmap(imgWidth, imgHeight, 1, 1, null); - int /*long*/ oldMaskBitmap = OS.SelectObject(maskHdc, maskBitmap); - OS.SetBkColor(srcHdc, transparentColor); - OS.BitBlt(maskHdc, 0, 0, imgWidth, imgHeight, srcHdc, 0, 0, OS.SRCCOPY); - if (originalColors != null) OS.SetDIBColorTable(srcHdc, 0, 1 << bm.bmBitsPixel, originalColors); - - if (OS.GetDeviceCaps(handle, OS.TECHNOLOGY) == OS.DT_RASPRINTER) { - /* Most printers do not support BitBlt(), draw the source bitmap transparently using clipping */ - drawBitmapTransparentByClipping(srcHdc, maskHdc, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple, imgWidth, imgHeight); - } else { - /* Draw the source bitmap transparently using invert/and mask/invert */ - int /*long*/ tempHdc = OS.CreateCompatibleDC(handle); - int /*long*/ tempBitmap = OS.CreateCompatibleBitmap(handle, destWidth, destHeight); - int /*long*/ oldTempBitmap = OS.SelectObject(tempHdc, tempBitmap); - OS.BitBlt(tempHdc, 0, 0, destWidth, destHeight, handle, destX, destY, OS.SRCCOPY); - if (!simple && (srcWidth != destWidth || srcHeight != destHeight)) { - if (!OS.IsWinCE) OS.SetStretchBltMode(tempHdc, OS.COLORONCOLOR); - OS.StretchBlt(tempHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, OS.SRCINVERT); - OS.StretchBlt(tempHdc, 0, 0, destWidth, destHeight, maskHdc, srcX, srcY, srcWidth, srcHeight, OS.SRCAND); - OS.StretchBlt(tempHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, OS.SRCINVERT); - } else { - OS.BitBlt(tempHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcY, OS.SRCINVERT); - OS.BitBlt(tempHdc, 0, 0, destWidth, destHeight, maskHdc, srcX, srcY, OS.SRCAND); - OS.BitBlt(tempHdc, 0, 0, destWidth, destHeight, srcHdc, srcX, srcY, OS.SRCINVERT); - } - OS.BitBlt(handle, destX, destY, destWidth, destHeight, tempHdc, 0, 0, OS.SRCCOPY); - OS.SelectObject(tempHdc, oldTempBitmap); - OS.DeleteDC(tempHdc); - OS.DeleteObject(tempBitmap); - } - OS.SelectObject(maskHdc, oldMaskBitmap); - OS.DeleteDC(maskHdc); - OS.DeleteObject(maskBitmap); - } - OS.SelectObject(srcHdc, oldSrcBitmap); - if (hBitmap != srcImage.handle) OS.DeleteObject(hBitmap); - OS.DeleteDC(srcHdc); -} - -void drawBitmap(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple, BITMAP bm, int imgWidth, int imgHeight) { - int /*long*/ srcHdc = OS.CreateCompatibleDC(handle); - int /*long*/ oldSrcBitmap = OS.SelectObject(srcHdc, srcImage.handle); - int rop2 = 0; - if (!OS.IsWinCE) { - rop2 = OS.GetROP2(handle); - } else { - rop2 = OS.SetROP2 (handle, OS.R2_COPYPEN); - OS.SetROP2 (handle, rop2); - } - int dwRop = rop2 == OS.R2_XORPEN ? OS.SRCINVERT : OS.SRCCOPY; - if (!simple && (srcWidth != destWidth || srcHeight != destHeight)) { - int mode = 0; - if (!OS.IsWinCE) mode = OS.SetStretchBltMode(handle, OS.COLORONCOLOR); - OS.StretchBlt(handle, destX, destY, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, dwRop); - if (!OS.IsWinCE) OS.SetStretchBltMode(handle, mode); - } else { - OS.BitBlt(handle, destX, destY, destWidth, destHeight, srcHdc, srcX, srcY, dwRop); - } - OS.SelectObject(srcHdc, oldSrcBitmap); - OS.DeleteDC(srcHdc); -} - -/** - * 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); - int /*long*/ gdipGraphics = data.gdipGraphics; - if (gdipGraphics != 0) { - Gdip.Graphics_TranslateTransform(gdipGraphics, data.gdipXOffset, data.gdipYOffset, Gdip.MatrixOrderPrepend); - Gdip.Graphics_DrawLine(gdipGraphics, data.gdipPen, x1, y1, x2, y2); - Gdip.Graphics_TranslateTransform(gdipGraphics, -data.gdipXOffset, -data.gdipYOffset, Gdip.MatrixOrderPrepend); - return; - } - if ((data.style & SWT.MIRRORED) != 0) { - if (data.lineWidth != 0 && data.lineWidth % 2 == 0) { - x1--; - x2--; - } - } - if (OS.IsWinCE) { - int [] points = new int [] {x1, y1, x2, y2}; - OS.Polyline (handle, points, points.length / 2); - } else { - OS.MoveToEx (handle, x1, y1, 0); - OS.LineTo (handle, x2, y2); - } - if (data.lineWidth <= 1) { - OS.SetPixel (handle, x2, y2, data.foreground); - } -} - -/** - * 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); - int /*long*/ gdipGraphics = data.gdipGraphics; - if (gdipGraphics != 0) { - Gdip.Graphics_TranslateTransform(gdipGraphics, data.gdipXOffset, data.gdipYOffset, Gdip.MatrixOrderPrepend); - Gdip.Graphics_DrawEllipse(gdipGraphics, data.gdipPen, x, y, width, height); - Gdip.Graphics_TranslateTransform(gdipGraphics, -data.gdipXOffset, -data.gdipYOffset, Gdip.MatrixOrderPrepend); - return; - } - if ((data.style & SWT.MIRRORED) != 0) { - if (data.lineWidth != 0 && data.lineWidth % 2 == 0) x--; - } - OS.Ellipse(handle, x, y, x + width + 1, y + height + 1); -} - -/** - * 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); - initGdip(); - checkGC(DRAW); - int /*long*/ gdipGraphics = data.gdipGraphics; - Gdip.Graphics_TranslateTransform(gdipGraphics, data.gdipXOffset, data.gdipYOffset, Gdip.MatrixOrderPrepend); - Gdip.Graphics_DrawPath(gdipGraphics, data.gdipPen, path.handle); - Gdip.Graphics_TranslateTransform(gdipGraphics, -data.gdipXOffset, -data.gdipYOffset, Gdip.MatrixOrderPrepend); -} - -/** - * 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); - if (data.gdipGraphics != 0) { - checkGC(DRAW); - Gdip.Graphics_FillRectangle(data.gdipGraphics, getFgBrush(), x, y, 1, 1); - return; - } - OS.SetPixel (handle, x, y, data.foreground); -} - -/** - * 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); - int /*long*/ gdipGraphics = data.gdipGraphics; - if (gdipGraphics != 0) { - Gdip.Graphics_TranslateTransform(gdipGraphics, data.gdipXOffset, data.gdipYOffset, Gdip.MatrixOrderPrepend); - Gdip.Graphics_DrawPolygon(gdipGraphics, data.gdipPen, pointArray, pointArray.length / 2); - Gdip.Graphics_TranslateTransform(gdipGraphics, -data.gdipXOffset, -data.gdipYOffset, Gdip.MatrixOrderPrepend); - return; - } - if ((data.style & SWT.MIRRORED) != 0) { - if (data.lineWidth != 0 && data.lineWidth % 2 == 0) { - for (int i = 0; i < pointArray.length; i+=2) { - pointArray[i]--; - } - } - } - OS.Polygon(handle, pointArray, pointArray.length / 2); - if ((data.style & SWT.MIRRORED) != 0) { - if (data.lineWidth != 0 && data.lineWidth % 2 == 0) { - for (int i = 0; i < pointArray.length; i+=2) { - pointArray[i]++; - } - } - } -} - -/** - * 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); - int /*long*/ gdipGraphics = data.gdipGraphics; - if (gdipGraphics != 0) { - Gdip.Graphics_TranslateTransform(gdipGraphics, data.gdipXOffset, data.gdipYOffset, Gdip.MatrixOrderPrepend); - Gdip.Graphics_DrawLines(gdipGraphics, data.gdipPen, pointArray, pointArray.length / 2); - Gdip.Graphics_TranslateTransform(gdipGraphics, -data.gdipXOffset, -data.gdipYOffset, Gdip.MatrixOrderPrepend); - return; - } - if ((data.style & SWT.MIRRORED) != 0) { - if (data.lineWidth != 0 && data.lineWidth % 2 == 0) { - for (int i = 0; i < pointArray.length; i+=2) { - pointArray[i]--; - } - } - } - OS.Polyline(handle, pointArray, pointArray.length / 2); - int length = pointArray.length; - if (length >= 2) { - if (data.lineWidth <= 1) { - OS.SetPixel (handle, pointArray[length - 2], pointArray[length - 1], data.foreground); - } - } - if ((data.style & SWT.MIRRORED) != 0) { - if (data.lineWidth != 0 && data.lineWidth % 2 == 0) { - for (int i = 0; i < pointArray.length; i+=2) { - pointArray[i]++; - } - } - } -} - -/** - * 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); - int /*long*/ gdipGraphics = data.gdipGraphics; - if (gdipGraphics != 0) { - if (width < 0) { - x = x + width; - width = -width; - } - if (height < 0) { - y = y + height; - height = -height; - } - Gdip.Graphics_TranslateTransform(gdipGraphics, data.gdipXOffset, data.gdipYOffset, Gdip.MatrixOrderPrepend); - Gdip.Graphics_DrawRectangle(gdipGraphics, data.gdipPen, x, y, width, height); - Gdip.Graphics_TranslateTransform(gdipGraphics, -data.gdipXOffset, -data.gdipYOffset, Gdip.MatrixOrderPrepend); - return; - } - if ((data.style & SWT.MIRRORED) != 0) { - /* - * Note that Rectangle() subtracts one pixel in MIRRORED mode when - * the pen was created with CreatePen() and its width is 0 or 1. - */ - if (data.lineWidth > 1) { - if ((data.lineWidth % 2) == 1) x++; - } else { - if (data.hPen != 0 && OS.GetObject(data.hPen, 0, 0) != LOGPEN.sizeof) { - x++; - } - } - } - OS.Rectangle (handle, x, y, x + width + 1, y + height + 1); -} - -/** - * 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.gdipGraphics != 0) { - drawRoundRectangleGdip(data.gdipGraphics, data.gdipPen, x, y, width, height, arcWidth, arcHeight); - return; - } - if ((data.style & SWT.MIRRORED) != 0) { - if (data.lineWidth != 0 && data.lineWidth % 2 == 0) x--; - } - if (OS.IsWinCE) { - /* - * Bug in WinCE PPC. On certain devices, RoundRect does not draw - * all the pixels. The workaround is to draw a round rectangle - * using lines and arcs. - */ - if (width == 0 || height == 0) return; - if (arcWidth == 0 || arcHeight == 0) { - drawRectangle(x, y, width, height); - return; - } - if (width < 0) { - x += width; - width = -width; - } - if (height < 0) { - y += height; - height = -height; - } - if (arcWidth < 0) arcWidth = -arcWidth; - if (arcHeight < 0) arcHeight = -arcHeight; - if (arcWidth > width) arcWidth = width; - if (arcHeight > height) arcHeight = height; - - if (arcWidth < width) { - drawLine(x+arcWidth/2, y, x+width-arcWidth/2, y); - drawLine(x+arcWidth/2, y+height, x+width-arcWidth/2, y+height); - } - if (arcHeight < height) { - drawLine(x, y+arcHeight/2, x, y+height-arcHeight/2); - drawLine(x+width, y+arcHeight/2, x+width, y+height-arcHeight/2); - } - if (arcWidth != 0 && arcHeight != 0) { - drawArc(x, y, arcWidth, arcHeight, 90, 90); - drawArc(x+width-arcWidth, y, arcWidth, arcHeight, 0, 90); - drawArc(x+width-arcWidth, y+height-arcHeight, arcWidth, arcHeight, 0, -90); - drawArc(x, y+height-arcHeight, arcWidth, arcHeight, 180, 90); - } - } else { - OS.RoundRect(handle, x,y,x+width+1,y+height+1, arcWidth, arcHeight); - } -} - -void drawRoundRectangleGdip (int /*long*/ gdipGraphics, int /*long*/ pen, int x, int y, int width, int height, int arcWidth, int arcHeight) { - 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; - - Gdip.Graphics_TranslateTransform(gdipGraphics, data.gdipXOffset, data.gdipYOffset, Gdip.MatrixOrderPrepend); - if (naw == 0 || nah == 0) { - Gdip.Graphics_DrawRectangle(gdipGraphics, data.gdipPen, x, y, width, height); - } else { - int /*long*/ path = Gdip.GraphicsPath_new(Gdip.FillModeAlternate); - if (path == 0) SWT.error(SWT.ERROR_NO_HANDLES); - if (nw > naw) { - if (nh > nah) { - Gdip.GraphicsPath_AddArc(path, nx + nw - naw, ny, naw, nah, 0, -90); - Gdip.GraphicsPath_AddArc(path, nx, ny, naw, nah, -90, -90); - Gdip.GraphicsPath_AddArc(path, nx, ny + nh - nah, naw, nah, -180, -90); - Gdip.GraphicsPath_AddArc(path, nx + nw - naw, ny + nh - nah, naw, nah, -270, -90); - } else { - Gdip.GraphicsPath_AddArc(path, nx + nw - naw, ny, naw, nh, -270, -180); - Gdip.GraphicsPath_AddArc(path, nx, ny, naw, nh, -90, -180); - } - } else { - if (nh > nah) { - Gdip.GraphicsPath_AddArc(path, nx, ny, nw, nah, 0, -180); - Gdip.GraphicsPath_AddArc(path, nx, ny + nh - nah, nw, nah, -180, -180); - } else { - Gdip.GraphicsPath_AddArc(path, nx, ny, nw, nh, 0, 360); - } - } - Gdip.GraphicsPath_CloseFigure(path); - Gdip.Graphics_DrawPath(gdipGraphics, pen, path); - Gdip.GraphicsPath_delete(path); - } - Gdip.Graphics_TranslateTransform(gdipGraphics, -data.gdipXOffset, -data.gdipYOffset, Gdip.MatrixOrderPrepend); -} - -/** - * 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) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (string == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); -// TCHAR buffer = new TCHAR (getCodePage(), string, false); - int length = string.length(); - if (length == 0) return; - char[] buffer = new char [length]; - string.getChars(0, length, buffer, 0); - int /*long*/ gdipGraphics = data.gdipGraphics; - if (gdipGraphics != 0) { - checkGC(FONT | FOREGROUND | (isTransparent ? 0 : BACKGROUND)); - int nGlyphs = (length * 3 / 2) + 16; - GCP_RESULTS result = new GCP_RESULTS(); - result.lStructSize = GCP_RESULTS.sizeof; - result.nGlyphs = nGlyphs; - int /*long*/ hHeap = OS.GetProcessHeap(); - int /*long*/ lpDx = result.lpDx = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, nGlyphs * 4); - int /*long*/ lpGlyphs = result.lpGlyphs = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, nGlyphs * 2); - int dwFlags = OS.GCP_GLYPHSHAPE | OS.GCP_REORDER | OS.GCP_LIGATE; - int /*long*/ hdc = Gdip.Graphics_GetHDC(gdipGraphics); - int /*long*/ hFont = data.hGDIFont; - if (hFont == 0 && data.font != null) hFont = data.font.handle; - int /*long*/ oldFont = 0; - if (hFont != 0) oldFont = OS.SelectObject(hdc, hFont); - if ((data.style & SWT.MIRRORED) != 0) OS.SetLayout(hdc, OS.GetLayout(hdc) | OS.LAYOUT_RTL); - OS.GetCharacterPlacementW(hdc, buffer, length, 0, result, dwFlags); - if ((data.style & SWT.MIRRORED) != 0) OS.SetLayout(hdc, OS.GetLayout(hdc) & ~OS.LAYOUT_RTL); - TEXTMETRIC lptm = OS.IsUnicode ? (TEXTMETRIC)new TEXTMETRICW() : new TEXTMETRICA(); - OS.GetTextMetrics(hdc, lptm); - if (hFont != 0) OS.SelectObject(hdc, oldFont); - Gdip.Graphics_ReleaseHDC(gdipGraphics, hdc); - nGlyphs = result.nGlyphs; - int drawX = x, drawY = y + lptm.tmAscent; - int[] dx = new int[nGlyphs]; - OS.MoveMemory(dx, result.lpDx, nGlyphs * 4); - float[] points = new float[dx.length * 2]; - for (int i = 0, j = 0; i < dx.length; i++) { - points[j++] = drawX; - points[j++] = drawY; - drawX += dx[i]; - } - RectF bounds = null; - if (!isTransparent || (data.style & SWT.MIRRORED) != 0) { - bounds = new RectF(); - Gdip.Graphics_MeasureDriverString(gdipGraphics, lpGlyphs, nGlyphs, data.gdipFont, points, 0, 0, bounds); - if (!isTransparent) { - Gdip.Graphics_FillRectangle(gdipGraphics, data.gdipBrush, x, y, Math.round(bounds.Width), Math.round(bounds.Height)); - } - } - int gstate = 0; - int /*long*/ brush = getFgBrush(); - if ((data.style & SWT.MIRRORED) != 0) { - switch (Gdip.Brush_GetType(brush)) { - case Gdip.BrushTypeLinearGradient: - Gdip.LinearGradientBrush_ScaleTransform(brush, -1, 1, Gdip.MatrixOrderPrepend); - Gdip.LinearGradientBrush_TranslateTransform(brush, - 2 * x - bounds.Width, 0, Gdip.MatrixOrderPrepend); - break; - case Gdip.BrushTypeTextureFill: - Gdip.TextureBrush_ScaleTransform(brush, -1, 1, Gdip.MatrixOrderPrepend); - Gdip.TextureBrush_TranslateTransform(brush, - 2 * x - bounds.Width, 0, Gdip.MatrixOrderPrepend); - break; - } - gstate = Gdip.Graphics_Save(gdipGraphics); - Gdip.Graphics_ScaleTransform(gdipGraphics, -1, 1, Gdip.MatrixOrderPrepend); - Gdip.Graphics_TranslateTransform(gdipGraphics, - 2 * x - bounds.Width, 0, Gdip.MatrixOrderPrepend); - } - Gdip.Graphics_DrawDriverString(gdipGraphics, lpGlyphs, result.nGlyphs, data.gdipFont, brush, points, 0, 0); - if ((data.style & SWT.MIRRORED) != 0) { - switch (Gdip.Brush_GetType(brush)) { - case Gdip.BrushTypeLinearGradient: - Gdip.LinearGradientBrush_ResetTransform(brush); - break; - case Gdip.BrushTypeTextureFill: - Gdip.TextureBrush_ResetTransform(brush); - break; - } - Gdip.Graphics_Restore(gdipGraphics, gstate); - } - OS.HeapFree(hHeap, 0, lpGlyphs); - OS.HeapFree(hHeap, 0, lpDx); - return; - } - int rop2 = 0; - if (OS.IsWinCE) { - rop2 = OS.SetROP2(handle, OS.R2_COPYPEN); - OS.SetROP2(handle, rop2); - } else { - rop2 = OS.GetROP2(handle); - } - checkGC(FONT | FOREGROUND_TEXT | BACKGROUND_TEXT); - int oldBkMode = OS.SetBkMode(handle, isTransparent ? OS.TRANSPARENT : OS.OPAQUE); - RECT rect = null; - SIZE size = null; - int flags = 0; - if ((data.style & SWT.MIRRORED) != 0) { - if (!isTransparent) { - size = new SIZE(); - OS.GetTextExtentPoint32W(handle, buffer, length, size); - rect = new RECT (); - rect.left = x; - rect.right = x + size.cx; - rect.top = y; - rect.bottom = y + size.cy; - flags = OS.ETO_CLIPPED; - } - x--; - } - if (rop2 != OS.R2_XORPEN) { - OS.ExtTextOutW(handle, x, y, flags, rect, buffer, length, null); - } else { - int foreground = OS.GetTextColor(handle); - if (isTransparent) { - if (size == null) { - size = new SIZE(); - OS.GetTextExtentPoint32W(handle, buffer, length, size); - } - int width = size.cx, height = size.cy; - int /*long*/ hBitmap = OS.CreateCompatibleBitmap(handle, width, height); - if (hBitmap == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int /*long*/ memDC = OS.CreateCompatibleDC(handle); - int /*long*/ hOldBitmap = OS.SelectObject(memDC, hBitmap); - OS.PatBlt(memDC, 0, 0, width, height, OS.BLACKNESS); - OS.SetBkMode(memDC, OS.TRANSPARENT); - OS.SetTextColor(memDC, foreground); - OS.SelectObject(memDC, OS.GetCurrentObject(handle, OS.OBJ_FONT)); - OS.ExtTextOutW(memDC, 0, 0, 0, null, buffer, length, null); - OS.BitBlt(handle, x, y, width, height, memDC, 0, 0, OS.SRCINVERT); - OS.SelectObject(memDC, hOldBitmap); - OS.DeleteDC(memDC); - OS.DeleteObject(hBitmap); - } else { - int background = OS.GetBkColor(handle); - OS.SetTextColor(handle, foreground ^ background); - OS.ExtTextOutW(handle, x, y, flags, rect, buffer, length, null); - OS.SetTextColor(handle, foreground); - } - } - OS.SetBkMode(handle, oldBkMode); -} - -/** - * 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); - if (string.length() == 0) return; - int /*long*/ gdipGraphics = data.gdipGraphics; - if (gdipGraphics != 0) { - checkGC(FONT | FOREGROUND | ((flags & SWT.DRAW_TRANSPARENT) != 0 ? 0 : BACKGROUND)); - int length = string.length(); - char[] buffer = new char [length]; - string.getChars(0, length, buffer, 0); - PointF pt = new PointF(); - int /*long*/ format = Gdip.StringFormat_Clone(Gdip.StringFormat_GenericTypographic()); - int formatFlags = Gdip.StringFormat_GetFormatFlags(format) | Gdip.StringFormatFlagsMeasureTrailingSpaces; - if ((data.style & SWT.MIRRORED) != 0) formatFlags |= Gdip.StringFormatFlagsDirectionRightToLeft; - Gdip.StringFormat_SetFormatFlags(format, formatFlags); - float[] tabs = (flags & SWT.DRAW_TAB) != 0 ? new float[]{measureSpace(data.gdipFont, format) * 8} : new float[1]; - Gdip.StringFormat_SetTabStops(format, 0, tabs.length, tabs); - int hotkeyPrefix = (flags & SWT.DRAW_MNEMONIC) != 0 ? Gdip.HotkeyPrefixShow : Gdip.HotkeyPrefixNone; - if ((flags & SWT.DRAW_MNEMONIC) != 0 && (data.uiState & OS.UISF_HIDEACCEL) != 0) hotkeyPrefix = Gdip.HotkeyPrefixHide; - Gdip.StringFormat_SetHotkeyPrefix(format, hotkeyPrefix); - if ((flags & SWT.DRAW_TRANSPARENT) == 0) { - RectF bounds = new RectF(); - Gdip.Graphics_MeasureString(gdipGraphics, buffer, length, data.gdipFont, pt, format, bounds); - Gdip.Graphics_FillRectangle(gdipGraphics, data.gdipBrush, x, y, Math.round(bounds.Width), Math.round(bounds.Height)); - } - int gstate = 0; - int /*long*/ brush = getFgBrush(); - if ((data.style & SWT.MIRRORED) != 0) { - switch (Gdip.Brush_GetType(brush)) { - case Gdip.BrushTypeLinearGradient: - Gdip.LinearGradientBrush_ScaleTransform(brush, -1, 1, Gdip.MatrixOrderPrepend); - Gdip.LinearGradientBrush_TranslateTransform(brush, - 2 * x, 0, Gdip.MatrixOrderPrepend); - break; - case Gdip.BrushTypeTextureFill: - Gdip.TextureBrush_ScaleTransform(brush, -1, 1, Gdip.MatrixOrderPrepend); - Gdip.TextureBrush_TranslateTransform(brush, - 2 * x, 0, Gdip.MatrixOrderPrepend); - break; - } - gstate = Gdip.Graphics_Save(gdipGraphics); - Gdip.Graphics_ScaleTransform(gdipGraphics, -1, 1, Gdip.MatrixOrderPrepend); - Gdip.Graphics_TranslateTransform(gdipGraphics, - 2 * x, 0, Gdip.MatrixOrderPrepend); - } - pt.X = x; - pt.Y = y; - Gdip.Graphics_DrawString(gdipGraphics, buffer, length, data.gdipFont, pt, format, brush); - if ((data.style & SWT.MIRRORED) != 0) { - switch (Gdip.Brush_GetType(brush)) { - case Gdip.BrushTypeLinearGradient: - Gdip.LinearGradientBrush_ResetTransform(brush); - break; - case Gdip.BrushTypeTextureFill: - Gdip.TextureBrush_ResetTransform(brush); - break; - } - Gdip.Graphics_Restore(gdipGraphics, gstate); - } - Gdip.StringFormat_delete(format); - return; - } - TCHAR buffer = new TCHAR(getCodePage(), string, false); - int length = buffer.length(); - if (length == 0) return; - RECT rect = new RECT(); - /* - * Feature in Windows. For some reason DrawText(), the maximum - * value for the bottom and right coordinates for the RECT that - * is used to position the text is different on between Windows - * versions. If this value is larger than the maximum, nothing - * is drawn. On Windows 98, the limit is 0x7FFF. On Windows CE, - * NT, and 2000 it is 0x6FFFFFF. And on XP, it is 0x7FFFFFFF. - * The fix is to use the the smaller limit for Windows 98 and the - * larger limit on the other Windows platforms. - */ - int limit = OS.IsWin95 ? 0x7FFF : 0x6FFFFFF; - OS.SetRect(rect, x, y, limit, limit); - int uFormat = OS.DT_LEFT; - if ((flags & SWT.DRAW_DELIMITER) == 0) uFormat |= OS.DT_SINGLELINE; - if ((flags & SWT.DRAW_TAB) != 0) uFormat |= OS.DT_EXPANDTABS; - if ((flags & SWT.DRAW_MNEMONIC) == 0) uFormat |= OS.DT_NOPREFIX; - if ((flags & SWT.DRAW_MNEMONIC) != 0 && (data.uiState & OS.UISF_HIDEACCEL) != 0) { - uFormat |= OS.DT_HIDEPREFIX; - } - int rop2 = 0; - if (OS.IsWinCE) { - rop2 = OS.SetROP2(handle, OS.R2_COPYPEN); - OS.SetROP2(handle, rop2); - } else { - rop2 = OS.GetROP2(handle); - } - checkGC(FONT | FOREGROUND_TEXT | BACKGROUND_TEXT); - int oldBkMode = OS.SetBkMode(handle, (flags & SWT.DRAW_TRANSPARENT) != 0 ? OS.TRANSPARENT : OS.OPAQUE); - if (rop2 != OS.R2_XORPEN) { - OS.DrawText(handle, buffer, length, rect, uFormat); - } else { - int foreground = OS.GetTextColor(handle); - if ((flags & SWT.DRAW_TRANSPARENT) != 0) { - OS.DrawText(handle, buffer, buffer.length(), rect, uFormat | OS.DT_CALCRECT); - int width = rect.right - rect.left; - int height = rect.bottom - rect.top; - int /*long*/ hBitmap = OS.CreateCompatibleBitmap(handle, width, height); - if (hBitmap == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int /*long*/ memDC = OS.CreateCompatibleDC(handle); - int /*long*/ hOldBitmap = OS.SelectObject(memDC, hBitmap); - OS.PatBlt(memDC, 0, 0, width, height, OS.BLACKNESS); - OS.SetBkMode(memDC, OS.TRANSPARENT); - OS.SetTextColor(memDC, foreground); - OS.SelectObject(memDC, OS.GetCurrentObject(handle, OS.OBJ_FONT)); - OS.SetRect(rect, 0, 0, 0x7FFF, 0x7FFF); - OS.DrawText(memDC, buffer, length, rect, uFormat); - OS.BitBlt(handle, x, y, width, height, memDC, 0, 0, OS.SRCINVERT); - OS.SelectObject(memDC, hOldBitmap); - OS.DeleteDC(memDC); - OS.DeleteObject(hBitmap); - } else { - int background = OS.GetBkColor(handle); - OS.SetTextColor(handle, foreground ^ background); - OS.DrawText(handle, buffer, length, rect, uFormat); - OS.SetTextColor(handle, foreground); - } - } - OS.SetBkMode(handle, oldBkMode); -} - -/** - * 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) { - return (object == this) || ((object instanceof GC) && (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 (width < 0) { - x = x + width; - width = -width; - } - if (height < 0) { - y = y + height; - height = -height; - } - if (width == 0 || height == 0 || arcAngle == 0) return; - int /*long*/ gdipGraphics = data.gdipGraphics; - if (gdipGraphics != 0) { - if (width == height) { - Gdip.Graphics_FillPie(gdipGraphics, data.gdipBrush, x, y, width, height, -startAngle, -arcAngle); - } else { - int state = Gdip.Graphics_Save(gdipGraphics); - Gdip.Graphics_TranslateTransform(gdipGraphics, x, y, Gdip.MatrixOrderPrepend); - Gdip.Graphics_ScaleTransform(gdipGraphics, width, height, Gdip.MatrixOrderPrepend); - Gdip.Graphics_FillPie(gdipGraphics, data.gdipBrush, 0, 0, 1, 1, -startAngle, -arcAngle); - Gdip.Graphics_Restore(gdipGraphics, state); - } - return; - } - - if ((data.style & SWT.MIRRORED) != 0) x--; - /* - * Feature in WinCE. The function Pie is not present in the - * WinCE SDK. The fix is to emulate it by using Polygon. - */ - if (OS.IsWinCE) { - /* compute arc with a simple linear interpolation */ - if (arcAngle < 0) { - startAngle += arcAngle; - arcAngle = -arcAngle; - } - boolean drawSegments = true; - if (arcAngle >= 360) { - arcAngle = 360; - drawSegments = false; - } - int[] points = new int[(arcAngle + 1) * 2 + (drawSegments ? 4 : 0)]; - int cteX = 2 * x + width; - int cteY = 2 * y + height; - int index = (drawSegments ? 2 : 0); - for (int i = 0; i <= arcAngle; i++) { - points[index++] = (Compatibility.cos(startAngle + i, width) + cteX) >> 1; - points[index++] = (cteY - Compatibility.sin(startAngle + i, height)) >> 1; - } - if (drawSegments) { - points[0] = points[points.length - 2] = cteX >> 1; - points[1] = points[points.length - 1] = cteY >> 1; - } - OS.Polygon(handle, points, points.length / 2); - } else { - int x1, y1, x2, y2,tmp; - boolean isNegative; - if (arcAngle >= 360 || arcAngle <= -360) { - x1 = x2 = x + width; - y1 = y2 = y + height / 2; - } else { - isNegative = arcAngle < 0; - - arcAngle = arcAngle + startAngle; - if (isNegative) { - // swap angles - tmp = startAngle; - startAngle = arcAngle; - arcAngle = tmp; - } - x1 = Compatibility.cos(startAngle, width) + x + width/2; - y1 = -1 * Compatibility.sin(startAngle, height) + y + height/2; - - x2 = Compatibility.cos(arcAngle, width) + x + width/2; - y2 = -1 * Compatibility.sin(arcAngle, height) + y + height/2; - } - OS.Pie(handle, x, y, x + width + 1, y + height + 1, x1, y1, x2, y2); - } -} - -/** - * 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; - - 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; - } - if (data.gdipGraphics != 0) { - initGdip(); - PointF p1= new PointF(), p2 = new PointF(); - p1.X = x; - p1.Y = y; - if (vertical) { - p2.X = p1.X; - p2.Y = p1.Y + height; - } else { - p2.X = p1.X + width; - p2.Y = p1.Y; - } - int rgb = ((fromRGB.red & 0xFF) << 16) | ((fromRGB.green & 0xFF) << 8) | (fromRGB.blue & 0xFF); - int /*long*/ fromGpColor = Gdip.Color_new(data.alpha << 24 | rgb); - if (fromGpColor == 0) SWT.error(SWT.ERROR_NO_HANDLES); - rgb = ((toRGB.red & 0xFF) << 16) | ((toRGB.green & 0xFF) << 8) | (toRGB.blue & 0xFF); - int /*long*/ toGpColor = Gdip.Color_new(data.alpha << 24 | rgb); - if (toGpColor == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int /*long*/ brush = Gdip.LinearGradientBrush_new(p1, p2, fromGpColor, toGpColor); - Gdip.Graphics_FillRectangle(data.gdipGraphics, brush, x, y, width, height); - Gdip.LinearGradientBrush_delete(brush); - Gdip.Color_delete(fromGpColor); - Gdip.Color_delete(toGpColor); - return; - } - /* Use GradientFill if supported, only on Windows 98, 2000 and newer. */ - /* - * Bug in Windows: On Windows 2000 when the device is a printer, - * GradientFill swaps red and blue color components, causing the - * gradient to be printed in the wrong color. On Windows 98 when - * the device is a printer, GradientFill does not fill completely - * to the right edge of the rectangle. The fix is not to use - * GradientFill for printer devices. - */ - int rop2 = 0; - if (OS.IsWinCE) { - rop2 = OS.SetROP2(handle, OS.R2_COPYPEN); - OS.SetROP2(handle, rop2); - } else { - rop2 = OS.GetROP2(handle); - } - if (OS.IsWinNT && rop2 != OS.R2_XORPEN && OS.GetDeviceCaps(handle, OS.TECHNOLOGY) != OS.DT_RASPRINTER) { - final int /*long*/ hHeap = OS.GetProcessHeap(); - final int /*long*/ pMesh = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, GRADIENT_RECT.sizeof + TRIVERTEX.sizeof * 2); - if (pMesh == 0) SWT.error(SWT.ERROR_NO_HANDLES); - final int /*long*/ pVertex = pMesh + GRADIENT_RECT.sizeof; - - GRADIENT_RECT gradientRect = new GRADIENT_RECT(); - gradientRect.UpperLeft = 0; - gradientRect.LowerRight = 1; - OS.MoveMemory(pMesh, gradientRect, GRADIENT_RECT.sizeof); - - TRIVERTEX trivertex = new TRIVERTEX(); - trivertex.x = x; - trivertex.y = y; - trivertex.Red = (short)((fromRGB.red << 8) | fromRGB.red); - trivertex.Green = (short)((fromRGB.green << 8) | fromRGB.green); - trivertex.Blue = (short)((fromRGB.blue << 8) | fromRGB.blue); - trivertex.Alpha = -1; - OS.MoveMemory(pVertex, trivertex, TRIVERTEX.sizeof); - - trivertex.x = x + width; - trivertex.y = y + height; - trivertex.Red = (short)((toRGB.red << 8) | toRGB.red); - trivertex.Green = (short)((toRGB.green << 8) | toRGB.green); - trivertex.Blue = (short)((toRGB.blue << 8) | toRGB.blue); - trivertex.Alpha = -1; - OS.MoveMemory(pVertex + TRIVERTEX.sizeof, trivertex, TRIVERTEX.sizeof); - - boolean success = OS.GradientFill(handle, pVertex, 2, pMesh, 1, vertical ? OS.GRADIENT_FILL_RECT_V : OS.GRADIENT_FILL_RECT_H); - OS.HeapFree(hHeap, 0, pMesh); - if (success) return; - } - - final int depth = OS.GetDeviceCaps(handle, OS.BITSPIXEL); - final int bitResolution = (depth >= 24) ? 8 : (depth >= 15) ? 5 : 0; - ImageData.fillGradientRectangle(this, data.device, - x, y, width, height, vertical, fromRGB, toRGB, - bitResolution, bitResolution, bitResolution); -} - -/** - * 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.gdipGraphics != 0) { - Gdip.Graphics_FillEllipse(data.gdipGraphics, data.gdipBrush, x, y, width, height); - return; - } - if ((data.style & SWT.MIRRORED) != 0) x--; - OS.Ellipse(handle, x, y, x + width + 1, y + height + 1); -} - -/** - * 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); - initGdip(); - checkGC(FILL); - int mode = OS.GetPolyFillMode(handle) == OS.WINDING ? Gdip.FillModeWinding : Gdip.FillModeAlternate; - Gdip.GraphicsPath_SetFillMode(path.handle, mode); - Gdip.Graphics_FillPath(data.gdipGraphics, data.gdipBrush, path.handle); -} - -/** - * 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.gdipGraphics != 0) { - int mode = OS.GetPolyFillMode(handle) == OS.WINDING ? Gdip.FillModeWinding : Gdip.FillModeAlternate; - Gdip.Graphics_FillPolygon(data.gdipGraphics, data.gdipBrush, pointArray, pointArray.length / 2, mode); - return; - } - if ((data.style & SWT.MIRRORED) != 0) { - for (int i = 0; i < pointArray.length; i+=2) { - pointArray[i]--; - } - } - OS.Polygon(handle, pointArray, pointArray.length / 2); - if ((data.style & SWT.MIRRORED) != 0) { - for (int i = 0; i < pointArray.length; i+=2) { - pointArray[i]++; - } - } -} - -/** - * 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.gdipGraphics != 0) { - if (width < 0) { - x = x + width; - width = -width; - } - if (height < 0) { - y = y + height; - height = -height; - } - Gdip.Graphics_FillRectangle(data.gdipGraphics, data.gdipBrush, x, y, width, height); - return; - } - int rop2 = 0; - if (OS.IsWinCE) { - rop2 = OS.SetROP2(handle, OS.R2_COPYPEN); - OS.SetROP2(handle, rop2); - } else { - rop2 = OS.GetROP2(handle); - } - int dwRop = rop2 == OS.R2_XORPEN ? OS.PATINVERT : OS.PATCOPY; - OS.PatBlt(handle, x, y, width, height, dwRop); -} - -/** - * 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 (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.gdipGraphics != 0) { - fillRoundRectangleGdip(data.gdipGraphics, data.gdipBrush, x, y, width, height, arcWidth, arcHeight); - return; - } - if ((data.style & SWT.MIRRORED) != 0) x--; - OS.RoundRect(handle, x,y,x+width+1,y+height+1,arcWidth, arcHeight); -} - -void fillRoundRectangleGdip (int /*long*/ gdipGraphics, int /*long*/ brush, int x, int y, int width, int height, int arcWidth, int arcHeight) { - 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 == 0 || nah == 0) { - Gdip.Graphics_FillRectangle(data.gdipGraphics, data.gdipBrush, x, y, width, height); - } else { - int /*long*/ path = Gdip.GraphicsPath_new(Gdip.FillModeAlternate); - if (path == 0) SWT.error(SWT.ERROR_NO_HANDLES); - if (nw > naw) { - if (nh > nah) { - Gdip.GraphicsPath_AddArc(path, nx + nw - naw, ny, naw, nah, 0, -90); - Gdip.GraphicsPath_AddArc(path, nx, ny, naw, nah, -90, -90); - Gdip.GraphicsPath_AddArc(path, nx, ny + nh - nah, naw, nah, -180, -90); - Gdip.GraphicsPath_AddArc(path, nx + nw - naw, ny + nh - nah, naw, nah, -270, -90); - } else { - Gdip.GraphicsPath_AddArc(path, nx + nw - naw, ny, naw, nh, -270, -180); - Gdip.GraphicsPath_AddArc(path, nx, ny, naw, nh, -90, -180); - } - } else { - if (nh > nah) { - Gdip.GraphicsPath_AddArc(path, nx, ny, nw, nah, 0, -180); - Gdip.GraphicsPath_AddArc(path, nx, ny + nh - nah, nw, nah, -180, -180); - } else { - Gdip.GraphicsPath_AddArc(path, nx, ny, nw, nh, 0, 360); - } - } - Gdip.GraphicsPath_CloseFigure(path); - Gdip.Graphics_FillPath(gdipGraphics, brush, path); - Gdip.GraphicsPath_delete(path); - } -} - -void flush () { - if (data.gdipGraphics != 0) { - Gdip.Graphics_Flush(data.gdipGraphics, 0); - /* - * Note Flush() does not flush the output to the - * underline HDC. This is done by calling GetHDC() - * followed by ReleaseHDC(). - */ - int /*long*/ hdc = Gdip.Graphics_GetHDC(data.gdipGraphics); - Gdip.Graphics_ReleaseHDC(data.gdipGraphics, hdc); - } -} - -/** - * 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); - checkGC(FONT); - if (OS.IsWinCE) { - SIZE size = new SIZE(); - OS.GetTextExtentPoint32W(handle, new char[]{ch}, 1, size); - return size.cx; - } - int tch = ch; - if (ch > 0x7F) { - TCHAR buffer = new TCHAR(getCodePage(), ch, false); - tch = buffer.tcharAt(0); - } - int[] width = new int[1]; - OS.GetCharWidth(handle, tch, tch, width); - return width[0]; -} - -/** - * 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 data.gdipGraphics != 0; -} - -/** - * 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); - if (data.gdipGraphics == 0) return SWT.DEFAULT; - int mode = Gdip.Graphics_GetSmoothingMode(data.gdipGraphics); - switch (mode) { - case Gdip.SmoothingModeDefault: return SWT.DEFAULT; - case Gdip.SmoothingModeHighSpeed: - case Gdip.SmoothingModeNone: return SWT.OFF; - case Gdip.SmoothingModeAntiAlias: - case Gdip.SmoothingModeAntiAlias8x8: - case Gdip.SmoothingModeHighQuality: return SWT.ON; - } - return SWT.DEFAULT; -} - -/** - * 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.win32_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_GRAPHIC_DISPOSED); - return data.backgroundPattern; -} - -/** - * 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); - checkGC(FONT); - - /* GetCharABCWidths only succeeds on truetype fonts */ - if (!OS.IsWinCE) { - int tch = ch; - if (ch > 0x7F) { - TCHAR buffer = new TCHAR(getCodePage(), ch, false); - tch = buffer.tcharAt (0); - } - int[] width = new int[3]; - if (OS.GetCharABCWidths(handle, tch, tch, width)) { - return width[1]; - } - } - - /* It wasn't a truetype font */ - TEXTMETRIC lptm = OS.IsUnicode ? (TEXTMETRIC)new TEXTMETRICW() : new TEXTMETRICA(); - OS.GetTextMetrics(handle, lptm); - SIZE size = new SIZE(); - OS.GetTextExtentPoint32W(handle, new char[]{ch}, 1, size); - return size.cx - lptm.tmOverhang; -} - -/** - * 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); - int /*long*/ gdipGraphics = data.gdipGraphics; - if (gdipGraphics != 0) { - Rect rect = new Rect(); - Gdip.Graphics_SetPixelOffsetMode(gdipGraphics, Gdip.PixelOffsetModeNone); - Gdip.Graphics_GetVisibleClipBounds(gdipGraphics, rect); - Gdip.Graphics_SetPixelOffsetMode(gdipGraphics, Gdip.PixelOffsetModeHalf); - return new Rectangle(rect.X, rect.Y, rect.Width, rect.Height); - } - RECT rect = new RECT(); - OS.GetClipBox(handle, rect); - return new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); -} - -/** - * 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); - int /*long*/ gdipGraphics = data.gdipGraphics; - if (gdipGraphics != 0) { - int /*long*/ rgn = Gdip.Region_new(); - Gdip.Graphics_GetClip(data.gdipGraphics, rgn); - if (Gdip.Region_IsInfinite(rgn, gdipGraphics)) { - Rect rect = new Rect(); - Gdip.Graphics_SetPixelOffsetMode(gdipGraphics, Gdip.PixelOffsetModeNone); - Gdip.Graphics_GetVisibleClipBounds(gdipGraphics, rect); - Gdip.Graphics_SetPixelOffsetMode(gdipGraphics, Gdip.PixelOffsetModeHalf); - OS.SetRectRgn(region.handle, rect.X, rect.Y, rect.X + rect.Width, rect.Y + rect.Height); - } else { - int /*long*/ matrix = Gdip.Matrix_new(1, 0, 0, 1, 0, 0); - int /*long*/ identity = Gdip.Matrix_new(1, 0, 0, 1, 0, 0); - Gdip.Graphics_GetTransform(gdipGraphics, matrix); - Gdip.Graphics_SetTransform(gdipGraphics, identity); - int /*long*/ hRgn = Gdip.Region_GetHRGN(rgn, data.gdipGraphics); - Gdip.Graphics_SetTransform(gdipGraphics, matrix); - Gdip.Matrix_delete(identity); - Gdip.Matrix_delete(matrix); - if (!OS.IsWinCE) { - POINT pt = new POINT (); - OS.GetWindowOrgEx (handle, pt); - OS.OffsetRgn (hRgn, pt.x, pt.y); - } - OS.CombineRgn(region.handle, hRgn, 0, OS.RGN_COPY); - OS.DeleteObject(hRgn); - } - Gdip.Region_delete(rgn); - return; - } - POINT pt = new POINT (); - if (!OS.IsWinCE) OS.GetWindowOrgEx (handle, pt); - int result = OS.GetClipRgn (handle, region.handle); - if (result != 1) { - RECT rect = new RECT(); - OS.GetClipBox(handle, rect); - OS.SetRectRgn(region.handle, rect.left, rect.top, rect.right, rect.bottom); - } else { - OS.OffsetRgn (region.handle, pt.x, pt.y); - } - if (!OS.IsWinCE) { - int /*long*/ metaRgn = OS.CreateRectRgn (0, 0, 0, 0); - if (OS.GetMetaRgn (handle, metaRgn) != 0) { - OS.OffsetRgn (metaRgn, pt.x, pt.y); - OS.CombineRgn (region.handle, metaRgn, region.handle, OS.RGN_AND); - } - OS.DeleteObject(metaRgn); - int /*long*/ hwnd = data.hwnd; - if (hwnd != 0 && data.ps != null) { - int /*long*/ sysRgn = OS.CreateRectRgn (0, 0, 0, 0); - if (OS.GetRandomRgn (handle, sysRgn, OS.SYSRGN) == 1) { - if (OS.WIN32_VERSION >= OS.VERSION(4, 10)) { - if ((OS.GetLayout(handle) & OS.LAYOUT_RTL) != 0) { - int nBytes = OS.GetRegionData (sysRgn, 0, null); - int [] lpRgnData = new int [nBytes / 4]; - OS.GetRegionData (sysRgn, nBytes, lpRgnData); - int /*long*/ newSysRgn = OS.ExtCreateRegion(new float [] {-1, 0, 0, 1, 0, 0}, nBytes, lpRgnData); - OS.DeleteObject(sysRgn); - sysRgn = newSysRgn; - } - } - if (OS.IsWinNT) { - OS.MapWindowPoints(0, hwnd, pt, 1); - OS.OffsetRgn(sysRgn, pt.x, pt.y); - } - OS.CombineRgn (region.handle, sysRgn, region.handle, OS.RGN_AND); - } - OS.DeleteObject(sysRgn); - } - } -} - -int getCodePage () { - if (OS.IsUnicode) return OS.CP_ACP; - int[] lpCs = new int[8]; - int cs = OS.GetTextCharset(handle); - OS.TranslateCharsetInfo(cs, lpCs, OS.TCI_SRCCHARSET); - return lpCs[1]; -} - -int /*long*/ getFgBrush() { - return data.foregroundPattern != null ? data.foregroundPattern.handle : data.gdipFgBrush; -} - -/** - * 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); - if (OS.IsWinCE) return SWT.FILL_EVEN_ODD; - return OS.GetPolyFillMode(handle) == OS.WINDING ? SWT.FILL_WINDING : SWT.FILL_EVEN_ODD; -} - -/** - * 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); - TEXTMETRIC lptm = OS.IsUnicode ? (TEXTMETRIC)new TEXTMETRICW() : new TEXTMETRICA(); - OS.GetTextMetrics(handle, lptm); - return FontMetrics.win32_new(lptm); -} - -/** - * 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_GRAPHIC_DISPOSED); - return Color.win32_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_GRAPHIC_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_GRAPHIC_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); - if (data.gdipGraphics == 0) return SWT.DEFAULT; - int mode = Gdip.Graphics_GetInterpolationMode(data.gdipGraphics); - switch (mode) { - case Gdip.InterpolationModeDefault: return SWT.DEFAULT; - case Gdip.InterpolationModeNearestNeighbor: return SWT.NONE; - case Gdip.InterpolationModeBilinear: - case Gdip.InterpolationModeLowQuality: return SWT.LOW; - case Gdip.InterpolationModeBicubic: - case Gdip.InterpolationModeHighQualityBilinear: - case Gdip.InterpolationModeHighQualityBicubic: - case Gdip.InterpolationModeHighQuality: 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); - if (data.gdipGraphics == 0) return SWT.DEFAULT; - int mode = Gdip.Graphics_GetTextRenderingHint(data.gdipGraphics); - switch (mode) { - case Gdip.TextRenderingHintSystemDefault: return SWT.DEFAULT; - case Gdip.TextRenderingHintSingleBitPerPixel: - case Gdip.TextRenderingHintSingleBitPerPixelGridFit: return SWT.OFF; - case Gdip.TextRenderingHintAntiAlias: - case Gdip.TextRenderingHintAntiAliasGridFit: - case Gdip.TextRenderingHintClearTypeGridFit: return SWT.ON; - } - return SWT.DEFAULT; -} - -/** - * 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); - int /*long*/ gdipGraphics = data.gdipGraphics; - if (gdipGraphics != 0) { - Gdip.Graphics_GetTransform(gdipGraphics, transform.handle); - int /*long*/ identity = identity(); - Gdip.Matrix_Invert(identity); - Gdip.Matrix_Multiply(transform.handle, identity, Gdip.MatrixOrderAppend); - Gdip.Matrix_delete(identity); - } 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); - int rop2 = 0; - if (OS.IsWinCE) { - rop2 = OS.SetROP2 (handle, OS.R2_COPYPEN); - OS.SetROP2 (handle, rop2); - } else { - rop2 = OS.GetROP2(handle); - } - return rop2 == OS.R2_XORPEN; -} - -void initGdip() { - data.device.checkGDIP(); - int /*long*/ gdipGraphics = data.gdipGraphics; - if (gdipGraphics != 0) return; - /* - * Feature in GDI+. The GDI+ clipping set with Graphics->SetClip() - * is always intersected with the GDI clipping at the time the - * GDI+ graphics is created. This means that the clipping - * cannot be reset. The fix is to clear the clipping before - * the GDI+ graphics is created and reset it afterwards. - */ - int /*long*/ hRgn = OS.CreateRectRgn(0, 0, 0, 0); - int result = OS.GetClipRgn(handle, hRgn); - if (!OS.IsWinCE) { - POINT pt = new POINT (); - OS.GetWindowOrgEx (handle, pt); - OS.OffsetRgn (hRgn, pt.x, pt.y); - } - OS.SelectClipRgn(handle, 0); - - /* - * Bug in GDI+. GDI+ does not work when the HDC layout is RTL. There - * are many issues like pixel corruption, but the most visible problem - * is that it does not have an effect when drawing to an bitmap. The - * fix is to clear the bit before creating the GDI+ graphics and install - * a mirroring matrix ourselves. - */ - if ((data.style & SWT.MIRRORED) != 0) { - OS.SetLayout(handle, OS.GetLayout(handle) & ~OS.LAYOUT_RTL); - } - - gdipGraphics = data.gdipGraphics = Gdip.Graphics_new(handle); - if (gdipGraphics == 0) SWT.error(SWT.ERROR_NO_HANDLES); - Gdip.Graphics_SetPageUnit(gdipGraphics, Gdip.UnitPixel); - Gdip.Graphics_SetPixelOffsetMode(gdipGraphics, Gdip.PixelOffsetModeHalf); - if ((data.style & SWT.MIRRORED) != 0) { - int /*long*/ matrix = identity(); - Gdip.Graphics_SetTransform(gdipGraphics, matrix); - Gdip.Matrix_delete(matrix); - } - if (result == 1) setClipping(hRgn); - OS.DeleteObject(hRgn); - data.state = 0; - if (data.hPen != 0) { - OS.SelectObject(handle, OS.GetStockObject(OS.NULL_PEN)); - OS.DeleteObject(data.hPen); - data.hPen = 0; - } - if (data.hBrush != 0) { - OS.SelectObject(handle, OS.GetStockObject(OS.NULL_BRUSH)); - OS.DeleteObject(data.hBrush); - data.hBrush = 0; - } -} - -int /*long*/ identity() { - if ((data.style & SWT.MIRRORED) != 0) { - int width = 0; - int technology = OS.GetDeviceCaps(handle, OS.TECHNOLOGY); - if (technology == OS.DT_RASPRINTER) { - width = OS.GetDeviceCaps(handle, OS.PHYSICALWIDTH); - } else { - Image image = data.image; - if (image != null) { - BITMAP bm = new BITMAP(); - OS.GetObject(image.handle, BITMAP.sizeof, bm); - width = bm.bmWidth; - } else { - int /*long*/ hwnd = OS.IsWinCE ? data.hwnd : OS.WindowFromDC(handle); - if (hwnd != 0) { - RECT rect = new RECT(); - OS.GetClientRect(hwnd, rect); - width = rect.right - rect.left; - } else { - int /*long*/ hBitmap = OS.GetCurrentObject(handle, OS.OBJ_BITMAP); - BITMAP bm = new BITMAP(); - OS.GetObject(hBitmap, BITMAP.sizeof, bm); - width = bm.bmWidth; - } - } - } - POINT pt = new POINT (); - if (!OS.IsWinCE) OS.GetWindowOrgEx (handle, pt); - return Gdip.Matrix_new(-1, 0, 0, 1, width + 2 * pt.x, 0); - } - return Gdip.Matrix_new(1, 0, 0, 1, 0, 0); -} - -void init(Drawable drawable, GCData data, int /*long*/ hDC) { - int foreground = data.foreground; - if (foreground != -1) { - data.state &= ~(FOREGROUND | FOREGROUND_TEXT | PEN); - } else { - data.foreground = OS.GetTextColor(hDC); - } - int background = data.background; - if (background != -1) { - data.state &= ~(BACKGROUND | BACKGROUND_TEXT | BRUSH); - } else { - data.background = OS.GetBkColor(hDC); - } - data.state &= ~(NULL_BRUSH | NULL_PEN); - Font font = data.font; - if (font != null) { - data.state &= ~FONT; - } else { - data.font = Font.win32_new(device, OS.GetCurrentObject(hDC, OS.OBJ_FONT)); - } - int /*long*/ hPalette = data.device.hPalette; - if (hPalette != 0) { - OS.SelectPalette(hDC, hPalette, true); - OS.RealizePalette(hDC); - } - Image image = data.image; - if (image != null) { - data.hNullBitmap = OS.SelectObject(hDC, image.handle); - image.memGC = this; - } - int layout = data.layout; - if (layout != -1) { - if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION(4, 10)) { - int flags = OS.GetLayout(hDC); - if ((flags & OS.LAYOUT_RTL) != (layout & OS.LAYOUT_RTL)) { - flags &= ~OS.LAYOUT_RTL; - OS.SetLayout(hDC, flags | layout); - } - if ((data.style & SWT.RIGHT_TO_LEFT) != 0) data.style |= SWT.MIRRORED; - } - } - this.drawable = drawable; - this.data = data; - handle = hDC; -} - -/** - * 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 (int)/*64*/handle; -} - -/** - * 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); - int /*long*/ gdipGraphics = data.gdipGraphics; - if (gdipGraphics != 0) { - int /*long*/ rgn = Gdip.Region_new(); - Gdip.Graphics_GetClip(data.gdipGraphics, rgn); - boolean isInfinite = Gdip.Region_IsInfinite(rgn, gdipGraphics); - Gdip.Region_delete(rgn); - return !isInfinite; - } - int /*long*/ region = OS.CreateRectRgn(0, 0, 0, 0); - int result = OS.GetClipRgn(handle, region); - OS.DeleteObject(region); - return result > 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; -} - -float measureSpace(int /*long*/ font, int /*long*/ format) { - PointF pt = new PointF(); - RectF bounds = new RectF(); - Gdip.Graphics_MeasureString(data.gdipGraphics, new char[]{' '}, 1, font, pt, format, bounds); - return bounds.Width; -} - -/** - * 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 && data.gdipGraphics != 0) return; - if (advanced) { - try { - initGdip(); - } catch (SWTException e) {} - } else { - disposeGdip(); - data.alpha = 0xFF; - data.backgroundPattern = data.foregroundPattern = null; - data.state = 0; - setClipping(0); - if ((data.style & SWT.MIRRORED) != 0) { - OS.SetLayout(handle, OS.GetLayout(handle) | OS.LAYOUT_RTL); - } - } -} - -/** - * 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); - if (data.gdipGraphics == 0 && antialias == SWT.DEFAULT) return; - int mode = 0; - switch (antialias) { - case SWT.DEFAULT: - mode = Gdip.SmoothingModeDefault; - break; - case SWT.OFF: - mode = Gdip.SmoothingModeNone; - break; - case SWT.ON: - mode = Gdip.SmoothingModeAntiAlias; - break; - default: - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - initGdip(); - Gdip.Graphics_SetSmoothingMode(data.gdipGraphics, mode); -} - -/** - * 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); - if (data.gdipGraphics == 0 && (alpha & 0xFF) == 0xFF) return; - initGdip(); - data.alpha = alpha & 0xFF; - data.state &= ~(BACKGROUND | FOREGROUND); -} - -/** - * 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); - if (data.backgroundPattern == null && data.background == color.handle) return; - data.backgroundPattern = null; - data.background = color.handle; - data.state &= ~(BACKGROUND | BACKGROUND_TEXT); -} - -/** - * 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.gdipGraphics == 0 && pattern == null) return; - initGdip(); - if (data.backgroundPattern == pattern) return; - data.backgroundPattern = pattern; - data.state &= ~BACKGROUND; -} - -void setClipping(int /*long*/ clipRgn) { - int /*long*/ hRgn = clipRgn; - int /*long*/ gdipGraphics = data.gdipGraphics; - if (gdipGraphics != 0) { - if (hRgn != 0) { - int /*long*/ region = Gdip.Region_new(hRgn); - Gdip.Graphics_SetClip(gdipGraphics, region, Gdip.CombineModeReplace); - Gdip.Region_delete(region); - } else { - Gdip.Graphics_ResetClip(gdipGraphics); - } - } else { - POINT pt = null; - if (hRgn != 0 && !OS.IsWinCE) { - pt = new POINT(); - OS.GetWindowOrgEx(handle, pt); - OS.OffsetRgn(hRgn, -pt.x, -pt.y); - } - OS.SelectClipRgn(handle, hRgn); - if (hRgn != 0 && !OS.IsWinCE) { - OS.OffsetRgn(hRgn, pt.x, pt.y); - } - } - if (hRgn != 0 && hRgn != clipRgn) { - OS.DeleteObject(hRgn); - } -} - -/** - * 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); - int /*long*/ hRgn = OS.CreateRectRgn(x, y, x + width, y + height); - setClipping(hRgn); - OS.DeleteObject(hRgn); -} - -/** - * 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) { - initGdip(); - int mode = OS.GetPolyFillMode(handle) == OS.WINDING ? Gdip.FillModeWinding : Gdip.FillModeAlternate; - Gdip.GraphicsPath_SetFillMode(path.handle, mode); - Gdip.Graphics_SetClipPath(data.gdipGraphics, path.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); -} - -/** - * 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); - if (OS.IsWinCE) return; - int mode = OS.ALTERNATE; - switch (rule) { - case SWT.FILL_WINDING: mode = OS.WINDING; break; - case SWT.FILL_EVEN_ODD: mode = OS.ALTERNATE; break; - default: - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - OS.SetPolyFillMode(handle, mode); -} - -/** - * 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); - if (data.foregroundPattern == null && color.handle == data.foreground) return; - data.foregroundPattern = null; - data.foreground = color.handle; - data.state &= ~(FOREGROUND | FOREGROUND_TEXT); -} - -/** - * 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.gdipGraphics == 0 && pattern == null) return; - initGdip(); - if (data.foregroundPattern == pattern) return; - data.foregroundPattern = pattern; - data.state &= ~FOREGROUND; -} - -/** - * 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); - if (data.gdipGraphics == 0 && interpolation == SWT.DEFAULT) return; - int mode = 0; - switch (interpolation) { - case SWT.DEFAULT: mode = Gdip.InterpolationModeDefault; break; - case SWT.NONE: mode = Gdip.InterpolationModeNearestNeighbor; break; - case SWT.LOW: mode = Gdip.InterpolationModeLowQuality; break; - case SWT.HIGH: mode = Gdip.InterpolationModeHighQuality; break; - default: - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - initGdip(); - Gdip.Graphics_SetInterpolationMode(data.gdipGraphics, mode); -} - -/** - * 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; - } - initGdip(); - 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); -} - -/** - * 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); - OS.SetROP2(handle, xor ? OS.R2_XORPEN : OS.R2_COPYPEN); -} - -/** - * 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); - if (data.gdipGraphics == 0 && antialias == SWT.DEFAULT) return; - int textMode = 0; - switch (antialias) { - case SWT.DEFAULT: - textMode = Gdip.TextRenderingHintSystemDefault; - break; - case SWT.OFF: - textMode = Gdip.TextRenderingHintSingleBitPerPixelGridFit; - break; - case SWT.ON: - int[] type = new int[1]; - OS.SystemParametersInfo(OS.SPI_GETFONTSMOOTHINGTYPE, 0, type, 0); - if (type[0] == OS.FE_FONTSMOOTHINGCLEARTYPE) { - textMode = Gdip.TextRenderingHintClearTypeGridFit; - } else { - textMode = Gdip.TextRenderingHintAntiAliasGridFit; - } - break; - default: - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - initGdip(); - Gdip.Graphics_SetTextRenderingHint(data.gdipGraphics, textMode); -} - -/** - * 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.gdipGraphics == 0 && transform == null) return; - initGdip(); - int /*long*/ identity = identity(); - if (transform != null) { - Gdip.Matrix_Multiply(identity, transform.handle, Gdip.MatrixOrderPrepend); - } - Gdip.Graphics_SetTransform(data.gdipGraphics, identity); - Gdip.Matrix_delete(identity); - 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) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (string == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); - checkGC(FONT); - int length = string.length(); - int /*long*/ gdipGraphics = data.gdipGraphics; - if (gdipGraphics != 0) { - RectF bounds = new RectF(); - char[] buffer; - if (length != 0) { - buffer = new char [length]; - string.getChars(0, length, buffer, 0); - } else { - buffer = new char[]{' '}; - } - int nGlyphs = (length * 3 / 2) + 16; - GCP_RESULTS result = new GCP_RESULTS(); - result.lStructSize = GCP_RESULTS.sizeof; - result.nGlyphs = nGlyphs; - int /*long*/ hHeap = OS.GetProcessHeap(); - int /*long*/ lpDx = result.lpDx = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, nGlyphs * 4); - int /*long*/ lpGlyphs = result.lpGlyphs = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, nGlyphs * 2); - int dwFlags = OS.GCP_GLYPHSHAPE | OS.GCP_REORDER | OS.GCP_LIGATE; - int /*long*/ hdc = Gdip.Graphics_GetHDC(gdipGraphics); - int /*long*/ hFont = data.hGDIFont; - if (hFont == 0 && data.font != null) hFont = data.font.handle; - int /*long*/ oldFont = 0; - if (hFont != 0) oldFont = OS.SelectObject(hdc, hFont); - if ((data.style & SWT.MIRRORED) != 0) OS.SetLayout(hdc, OS.GetLayout(hdc) | OS.LAYOUT_RTL); - OS.GetCharacterPlacementW(hdc, buffer, length, 0, result, dwFlags); - if ((data.style & SWT.MIRRORED) != 0) OS.SetLayout(hdc, OS.GetLayout(hdc) & ~OS.LAYOUT_RTL); - if (hFont != 0) OS.SelectObject(hdc, oldFont); - Gdip.Graphics_ReleaseHDC(gdipGraphics, hdc); - int drawX = 0; - int[] dx = new int[result.nGlyphs]; - OS.MoveMemory(dx, lpDx, result.nGlyphs * 4); - float[] points = new float[dx.length * 2]; - for (int i = 0, j = 0; i < dx.length; i++, j += 2) { - points[j] = drawX; - drawX += dx[i]; - } - Gdip.Graphics_MeasureDriverString(gdipGraphics, lpGlyphs, result.nGlyphs, data.gdipFont, points, 0, 0, bounds); - OS.HeapFree(hHeap, 0, lpGlyphs); - OS.HeapFree(hHeap, 0, lpDx); - return new Point(length == 0 ? 0 : Math.round(bounds.Width), Math.round(bounds.Height)); - } - SIZE size = new SIZE(); - if (length == 0) { -// OS.GetTextExtentPoint32(handle, SPACE, SPACE.length(), size); - OS.GetTextExtentPoint32W(handle, new char[]{' '}, 1, size); - return new Point(0, size.cy); - } else { -// TCHAR buffer = new TCHAR (getCodePage(), string, false); - char[] buffer = new char [length]; - string.getChars(0, length, buffer, 0); - OS.GetTextExtentPoint32W(handle, buffer, length, size); - return new Point(size.cx, size.cy); - } -} - -/** - * 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); - if (data.gdipGraphics != 0) { - PointF pt = new PointF(); - RectF bounds = new RectF(); - char[] buffer; - int length = string.length(); - if (length != 0) { - buffer = new char [length]; - string.getChars(0, length, buffer, 0); - } else { - buffer = new char[]{' '}; - } - int /*long*/ format = Gdip.StringFormat_Clone(Gdip.StringFormat_GenericTypographic()); - int formatFlags = Gdip.StringFormat_GetFormatFlags(format) | Gdip.StringFormatFlagsMeasureTrailingSpaces; - if ((data.style & SWT.MIRRORED) != 0) formatFlags |= Gdip.StringFormatFlagsDirectionRightToLeft; - Gdip.StringFormat_SetFormatFlags(format, formatFlags); - float[] tabs = (flags & SWT.DRAW_TAB) != 0 ? new float[]{measureSpace(data.gdipFont, format) * 8} : new float[1]; - Gdip.StringFormat_SetTabStops(format, 0, tabs.length, tabs); - Gdip.StringFormat_SetHotkeyPrefix(format, (flags & SWT.DRAW_MNEMONIC) != 0 ? Gdip.HotkeyPrefixShow : Gdip.HotkeyPrefixNone); - Gdip.Graphics_MeasureString(data.gdipGraphics, buffer, buffer.length, data.gdipFont, pt, format, bounds); - Gdip.StringFormat_delete(format); - return new Point(length == 0 ? 0 : Math.round(bounds.Width), Math.round(bounds.Height)); - } - if (string.length () == 0) { - SIZE size = new SIZE(); -// OS.GetTextExtentPoint32(handle, SPACE, SPACE.length(), size); - OS.GetTextExtentPoint32W(handle, new char [] {' '}, 1, size); - return new Point(0, size.cy); - } - RECT rect = new RECT(); - TCHAR buffer = new TCHAR(getCodePage(), string, false); - int uFormat = OS.DT_LEFT | OS.DT_CALCRECT; - if ((flags & SWT.DRAW_DELIMITER) == 0) uFormat |= OS.DT_SINGLELINE; - if ((flags & SWT.DRAW_TAB) != 0) uFormat |= OS.DT_EXPANDTABS; - if ((flags & SWT.DRAW_MNEMONIC) == 0) uFormat |= OS.DT_NOPREFIX; - OS.DrawText(handle, buffer, buffer.length(), rect, uFormat); - return new Point(rect.right, rect.bottom); -} - -/** - * 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 + "}"; -} - -/** - * 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> - */ -public static GC win32_new(Drawable drawable, GCData data) { - GC gc = new GC(); - int /*long*/ hDC = drawable.internal_new_GC(data); - gc.device = data.device; - gc.init(drawable, data, hDC); - 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 hDC the Windows HDC. - * @param data the data for the receiver. - * - * @return a new <code>GC</code> - */ -public static GC win32_new(int /*long*/ hDC, GCData data) { - GC gc = new GC(); - gc.device = data.device; - data.style |= SWT.LEFT_TO_RIGHT; - if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (4, 10)) { - int flags = OS.GetLayout (hDC); - if ((flags & OS.LAYOUT_RTL) != 0) { - data.style |= SWT.RIGHT_TO_LEFT | SWT.MIRRORED; - } - } - gc.init(null, data, hDC); - return gc; -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GCData.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GCData.java deleted file mode 100755 index 8ccb803401..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GCData.java +++ /dev/null @@ -1,64 +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.win32.*; - -/** - * 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 int foreground = -1; - public int background = -1; - public Font font; - public Pattern foregroundPattern; - public Pattern backgroundPattern; - public int lineStyle = SWT.LINE_SOLID; - public float lineWidth; - public int lineCap = SWT.CAP_FLAT; - public int lineJoin = SWT.JOIN_MITER; - public float lineDashesOffset; - public float[] lineDashes; - public float lineMiterLimit = 10; - public int alpha = 0xFF; - - public Image image; - public int /*long*/ hPen, hOldPen; - public int /*long*/ hBrush, hOldBrush; - public int /*long*/ hNullBitmap; - public int /*long*/ hwnd; - public PAINTSTRUCT ps; - public int layout = -1; - public int /*long*/ gdipGraphics; - public int /*long*/ gdipPen; - public int /*long*/ gdipBrush; - public int /*long*/ gdipFgBrush; - public int /*long*/ gdipBgBrush; - public int /*long*/ gdipFont; - public int /*long*/ hGDIFont; - public float gdipXOffset, gdipYOffset; - public int uiState = 0; - public boolean focusDrawn; -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java deleted file mode 100755 index 012f72e537..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java +++ /dev/null @@ -1,2129 +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.gdip.*; -import org.eclipse.swt.internal.win32.*; -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 /*long*/ handle; - - /** - * specifies the transparent pixel - */ - int transparentPixel = -1, transparentColor = -1; - - /** - * the GC which is drawing on the image - */ - GC memGC; - - /** - * the alpha data for the image - */ - byte[] alphaData; - - /** - * the global alpha value to be used for every pixel - */ - int alpha = -1; - - /** - * the image data used to create this image if it is a - * icon. Used only in WinCE - */ - ImageData data; - - /** - * width of the image - */ - int width = -1; - - /** - * height of the image - */ - int height = -1; - - /** - * specifies the default scanline padding - */ - static final int DEFAULT_SCANLINE_PAD = 4; - -/** - * Prevents uninitialized instances from being created outside the package. - */ -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); - device = this.device; - if (srcImage == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - if (srcImage.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - Rectangle rect = srcImage.getBounds(); - this.type = srcImage.type; - switch (flag) { - case SWT.IMAGE_COPY: { - switch (type) { - case SWT.BITMAP: - /* Get the HDC for the device */ - int /*long*/ hDC = device.internal_new_GC(null); - - /* Copy the bitmap */ - int /*long*/ hdcSource = OS.CreateCompatibleDC(hDC); - int /*long*/ hdcDest = OS.CreateCompatibleDC(hDC); - int /*long*/ hOldSrc = OS.SelectObject(hdcSource, srcImage.handle); - BITMAP bm = new BITMAP(); - OS.GetObject(srcImage.handle, BITMAP.sizeof, bm); - handle = OS.CreateCompatibleBitmap(hdcSource, rect.width, bm.bmBits != 0 ? -rect.height : rect.height); - if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int /*long*/ hOldDest = OS.SelectObject(hdcDest, handle); - OS.BitBlt(hdcDest, 0, 0, rect.width, rect.height, hdcSource, 0, 0, OS.SRCCOPY); - OS.SelectObject(hdcSource, hOldSrc); - OS.SelectObject(hdcDest, hOldDest); - OS.DeleteDC(hdcSource); - OS.DeleteDC(hdcDest); - - /* Release the HDC for the device */ - device.internal_dispose_GC(hDC, null); - - 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); - } - break; - case SWT.ICON: - if (OS.IsWinCE) { - init(srcImage.data); - } else { - handle = OS.CopyImage(srcImage.handle, OS.IMAGE_ICON, rect.width, rect.height, 0); - if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); - } - break; - default: - SWT.error(SWT.ERROR_INVALID_IMAGE); - } - break; - } - case SWT.IMAGE_DISABLE: { - ImageData data = srcImage.getImageData(); - PaletteData palette = data.palette; - RGB[] rgbs = new RGB[3]; - rgbs[0] = device.getSystemColor(SWT.COLOR_BLACK).getRGB(); - rgbs[1] = device.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW).getRGB(); - rgbs[2] = device.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND).getRGB(); - ImageData newData = new ImageData(rect.width, rect.height, 8, new PaletteData(rgbs)); - newData.alpha = data.alpha; - newData.alphaData = data.alphaData; - newData.maskData = data.maskData; - newData.maskPad = data.maskPad; - if (data.transparentPixel != -1) newData.transparentPixel = 0; - - /* Convert the pixels. */ - int[] scanline = new int[rect.width]; - int[] maskScanline = null; - ImageData mask = null; - if (data.maskData != null) mask = data.getTransparencyMask(); - if (mask != null) maskScanline = new int[rect.width]; - int redMask = palette.redMask; - int greenMask = palette.greenMask; - int blueMask = palette.blueMask; - int redShift = palette.redShift; - int greenShift = palette.greenShift; - int blueShift = palette.blueShift; - for (int y=0; y<rect.height; y++) { - int offset = y * newData.bytesPerLine; - data.getPixels(0, y, rect.width, scanline, 0); - if (mask != null) mask.getPixels(0, y, rect.width, maskScanline, 0); - for (int x=0; x<rect.width; x++) { - int pixel = scanline[x]; - if (!((data.transparentPixel != -1 && pixel == data.transparentPixel) || (mask != null && maskScanline[x] == 0))) { - int red, green, blue; - if (palette.isDirect) { - red = pixel & redMask; - red = (redShift < 0) ? red >>> -redShift : red << redShift; - green = pixel & greenMask; - green = (greenShift < 0) ? green >>> -greenShift : green << greenShift; - blue = pixel & blueMask; - blue = (blueShift < 0) ? blue >>> -blueShift : blue << blueShift; - } else { - red = palette.colors[pixel].red; - green = palette.colors[pixel].green; - blue = palette.colors[pixel].blue; - } - int intensity = red * red + green * green + blue * blue; - if (intensity < 98304) { - newData.data[offset] = (byte)1; - } else { - newData.data[offset] = (byte)2; - } - } - offset++; - } - } - init (newData); - break; - } - case SWT.IMAGE_GRAY: { - ImageData data = srcImage.getImageData(); - PaletteData palette = data.palette; - ImageData newData = data; - if (!palette.isDirect) { - /* Convert the palette entries to gray. */ - RGB [] rgbs = palette.getRGBs(); - for (int i=0; i<rgbs.length; i++) { - if (data.transparentPixel != i) { - RGB color = rgbs [i]; - int red = color.red; - int green = color.green; - int blue = color.blue; - int intensity = (red+red+green+green+green+green+green+blue) >> 3; - color.red = color.green = color.blue = intensity; - } - } - newData.palette = new PaletteData(rgbs); - } else { - /* Create a 8 bit depth image data with a gray palette. */ - RGB[] rgbs = new RGB[256]; - for (int i=0; i<rgbs.length; i++) { - rgbs[i] = new RGB(i, i, i); - } - newData = new ImageData(rect.width, rect.height, 8, new PaletteData(rgbs)); - newData.alpha = data.alpha; - newData.alphaData = data.alphaData; - newData.maskData = data.maskData; - newData.maskPad = data.maskPad; - if (data.transparentPixel != -1) newData.transparentPixel = 254; - - /* Convert the pixels. */ - int[] scanline = new int[rect.width]; - int redMask = palette.redMask; - int greenMask = palette.greenMask; - int blueMask = palette.blueMask; - int redShift = palette.redShift; - int greenShift = palette.greenShift; - int blueShift = palette.blueShift; - for (int y=0; y<rect.height; y++) { - int offset = y * newData.bytesPerLine; - data.getPixels(0, y, rect.width, scanline, 0); - for (int x=0; x<rect.width; x++) { - int pixel = scanline[x]; - if (pixel != data.transparentPixel) { - int red = pixel & redMask; - red = (redShift < 0) ? red >>> -redShift : red << redShift; - int green = pixel & greenMask; - green = (greenShift < 0) ? green >>> -greenShift : green << greenShift; - int blue = pixel & blueMask; - blue = (blueShift < 0) ? blue >>> -blueShift : blue << blueShift; - int intensity = (red+red+green+green+green+green+green+blue) >> 3; - if (newData.transparentPixel == intensity) intensity = 255; - newData.data[offset] = (byte)intensity; - } else { - newData.data[offset] = (byte)254; - } - offset++; - } - } - } - init (newData); - break; - } - default: - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - 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); - init(this.device, this, source, mask); - 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); - if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - initNative(filename); - if (this.handle == 0) init(new ImageData(filename)); - init(); -} - -void initNative(String filename) { - boolean gdip = true; - try { - device.checkGDIP(); - } catch (SWTException e) { - gdip = false; - } - /* - * Bug in GDI+. For some reason, Bitmap.LockBits() segment faults - * when loading GIF files in 64-bit Windows. The fix is to not use - * GDI+ image loading in this case. - */ - if (gdip && OS.PTR_SIZEOF == 8 && filename.toLowerCase().endsWith(".gif")) gdip = false; - if (gdip) { - int length = filename.length(); - char[] chars = new char[length+1]; - filename.getChars(0, length, chars, 0); - int /*long*/ bitmap = Gdip.Bitmap_new(chars, false); - if (bitmap != 0) { - int error = SWT.ERROR_NO_HANDLES; - int status = Gdip.Image_GetLastStatus(bitmap); - if (status == 0) { - if (filename.toLowerCase().endsWith(".ico")) { - this.type = SWT.ICON; - int /*long*/[] hicon = new int /*long*/[1]; - status = Gdip.Bitmap_GetHICON(bitmap, hicon); - this.handle = hicon[0]; - } else { - this.type = SWT.BITMAP; - int width = Gdip.Image_GetWidth(bitmap); - int height = Gdip.Image_GetHeight(bitmap); - int pixelFormat = Gdip.Image_GetPixelFormat(bitmap); - switch (pixelFormat) { - case Gdip.PixelFormat16bppRGB555: - case Gdip.PixelFormat16bppRGB565: - this.handle = createDIB(width, height, 16); - break; - case Gdip.PixelFormat24bppRGB: - this.handle = createDIB(width, height, 24); - break; - case Gdip.PixelFormat32bppRGB: - // These will loose either precision or transparency - case Gdip.PixelFormat16bppGrayScale: - case Gdip.PixelFormat48bppRGB: - case Gdip.PixelFormat32bppPARGB: - case Gdip.PixelFormat64bppARGB: - case Gdip.PixelFormat64bppPARGB: - this.handle = createDIB(width, height, 32); - break; - } - if (this.handle != 0) { - /* - * This performs better than getting the bits with Bitmap.LockBits(), - * but it cannot be used when there is transparency. - */ - int /*long*/ hDC = device.internal_new_GC(null); - int /*long*/ srcHDC = OS.CreateCompatibleDC(hDC); - int /*long*/ oldSrcBitmap = OS.SelectObject(srcHDC, this.handle); - int /*long*/ graphics = Gdip.Graphics_new(srcHDC); - if (graphics != 0) { - Rect rect = new Rect(); - rect.Width = width; - rect.Height = height; - status = Gdip.Graphics_DrawImage(graphics, bitmap, rect, 0, 0, width, height, Gdip.UnitPixel, 0, 0, 0); - if (status != 0) { - error = SWT.ERROR_INVALID_IMAGE; - OS.DeleteObject(handle); - this.handle = 0; - } - Gdip.Graphics_delete(graphics); - } - OS.SelectObject(srcHDC, oldSrcBitmap); - OS.DeleteDC(srcHDC); - device.internal_dispose_GC(hDC, null); - } else { - int /*long*/ lockedBitmapData = Gdip.BitmapData_new(); - if (lockedBitmapData != 0) { - status = Gdip.Bitmap_LockBits(bitmap, 0, 0, pixelFormat, lockedBitmapData); - if (status == 0) { - BitmapData bitmapData = new BitmapData(); - Gdip.MoveMemory(bitmapData, lockedBitmapData); - int stride = bitmapData.Stride; - int /*long*/ pixels = bitmapData.Scan0; - int depth = 0, scanlinePad = 4, transparentPixel = -1; - switch (bitmapData.PixelFormat) { - case Gdip.PixelFormat1bppIndexed: depth = 1; break; - case Gdip.PixelFormat4bppIndexed: depth = 4; break; - case Gdip.PixelFormat8bppIndexed: depth = 8; break; - case Gdip.PixelFormat16bppARGB1555: - case Gdip.PixelFormat16bppRGB555: - case Gdip.PixelFormat16bppRGB565: depth = 16; break; - case Gdip.PixelFormat24bppRGB: depth = 24; break; - case Gdip.PixelFormat32bppRGB: - case Gdip.PixelFormat32bppARGB: depth = 32; break; - } - if (depth != 0) { - PaletteData paletteData = null; - switch (bitmapData.PixelFormat) { - case Gdip.PixelFormat1bppIndexed: - case Gdip.PixelFormat4bppIndexed: - case Gdip.PixelFormat8bppIndexed: - int paletteSize = Gdip.Image_GetPaletteSize(bitmap); - int /*long*/ hHeap = OS.GetProcessHeap(); - int /*long*/ palette = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, paletteSize); - if (palette == 0) SWT.error(SWT.ERROR_NO_HANDLES); - Gdip.Image_GetPalette(bitmap, palette, paletteSize); - ColorPalette colorPalette = new ColorPalette(); - Gdip.MoveMemory(colorPalette, palette, ColorPalette.sizeof); - int[] entries = new int[colorPalette.Count]; - OS.MoveMemory(entries, palette + 8, entries.length * 4); - OS.HeapFree(hHeap, 0, palette); - RGB[] rgbs = new RGB[colorPalette.Count]; - paletteData = new PaletteData(rgbs); - for (int i = 0; i < entries.length; i++) { - if (((entries[i] >> 24) & 0xFF) == 0 && (colorPalette.Flags & Gdip.PaletteFlagsHasAlpha) != 0) { - transparentPixel = i; - } - rgbs[i] = new RGB(((entries[i] & 0xFF0000) >> 16), ((entries[i] & 0xFF00) >> 8), ((entries[i] & 0xFF) >> 0)); - } - break; - case Gdip.PixelFormat16bppARGB1555: - case Gdip.PixelFormat16bppRGB555: paletteData = new PaletteData(0x7C00, 0x3E0, 0x1F); break; - case Gdip.PixelFormat16bppRGB565: paletteData = new PaletteData(0xF800, 0x7E0, 0x1F); break; - case Gdip.PixelFormat24bppRGB: paletteData = new PaletteData(0xFF, 0xFF00, 0xFF0000); break; - case Gdip.PixelFormat32bppRGB: - case Gdip.PixelFormat32bppARGB: paletteData = new PaletteData(0xFF00, 0xFF0000, 0xFF000000); break; - } - byte[] data = new byte[stride * height], alphaData = null; - OS.MoveMemory(data, pixels, data.length); - switch (bitmapData.PixelFormat) { - case Gdip.PixelFormat16bppARGB1555: - alphaData = new byte[width * height]; - for (int i = 1, j = 0; i < data.length; i += 2, j++) { - alphaData[j] = (byte)((data[i] & 0x80) != 0 ? 255 : 0); - } - break; - case Gdip.PixelFormat32bppARGB: - alphaData = new byte[width * height]; - for (int i = 3, j = 0; i < data.length; i += 4, j++) { - alphaData[j] = data[i]; - } - break; - } - ImageData img = new ImageData(width, height, depth, paletteData, scanlinePad, data); - img.transparentPixel = transparentPixel; - img.alphaData = alphaData; - init(img); - } - Gdip.Bitmap_UnlockBits(bitmap, lockedBitmapData); - } else { - error = SWT.ERROR_INVALID_IMAGE; - } - Gdip.BitmapData_delete(lockedBitmapData); - } - } - } - } - Gdip.Bitmap_delete(bitmap); - if (status == 0) { - if (this.handle == 0) SWT.error(error); - } - } - } -} - -/** - * Create a DIB from a DDB without using GetDIBits. Note that - * the DDB should not be selected into a HDC. - */ -int /*long*/ createDIBFromDDB(int /*long*/ hDC, int /*long*/ hBitmap, int width, int height) { - - /* Determine the DDB depth */ - int bits = OS.GetDeviceCaps (hDC, OS.BITSPIXEL); - int planes = OS.GetDeviceCaps (hDC, OS.PLANES); - int depth = bits * planes; - - /* Determine the DIB palette */ - boolean isDirect = depth > 8; - RGB[] rgbs = null; - if (!isDirect) { - int numColors = 1 << depth; - byte[] logPalette = new byte[4 * numColors]; - OS.GetPaletteEntries(device.hPalette, 0, numColors, logPalette); - rgbs = new RGB[numColors]; - for (int i = 0; i < numColors; i++) { - rgbs[i] = new RGB(logPalette[i] & 0xFF, logPalette[i + 1] & 0xFF, logPalette[i + 2] & 0xFF); - } - } - - boolean useBitfields = OS.IsWinCE && (depth == 16 || depth == 32); - BITMAPINFOHEADER bmiHeader = new BITMAPINFOHEADER(); - bmiHeader.biSize = BITMAPINFOHEADER.sizeof; - bmiHeader.biWidth = width; - bmiHeader.biHeight = -height; - bmiHeader.biPlanes = 1; - bmiHeader.biBitCount = (short)depth; - if (useBitfields) bmiHeader.biCompression = OS.BI_BITFIELDS; - else bmiHeader.biCompression = OS.BI_RGB; - byte[] bmi; - if (isDirect) bmi = new byte[BITMAPINFOHEADER.sizeof + (useBitfields ? 12 : 0)]; - else bmi = new byte[BITMAPINFOHEADER.sizeof + rgbs.length * 4]; - OS.MoveMemory(bmi, bmiHeader, BITMAPINFOHEADER.sizeof); - - /* Set the rgb colors into the bitmap info */ - int offset = BITMAPINFOHEADER.sizeof; - if (isDirect) { - if (useBitfields) { - int redMask = 0; - int greenMask = 0; - int blueMask = 0; - switch (depth) { - case 16: - redMask = 0x7C00; - greenMask = 0x3E0; - blueMask = 0x1F; - /* little endian */ - bmi[offset] = (byte)((redMask & 0xFF) >> 0); - bmi[offset + 1] = (byte)((redMask & 0xFF00) >> 8); - bmi[offset + 2] = (byte)((redMask & 0xFF0000) >> 16); - bmi[offset + 3] = (byte)((redMask & 0xFF000000) >> 24); - bmi[offset + 4] = (byte)((greenMask & 0xFF) >> 0); - bmi[offset + 5] = (byte)((greenMask & 0xFF00) >> 8); - bmi[offset + 6] = (byte)((greenMask & 0xFF0000) >> 16); - bmi[offset + 7] = (byte)((greenMask & 0xFF000000) >> 24); - bmi[offset + 8] = (byte)((blueMask & 0xFF) >> 0); - bmi[offset + 9] = (byte)((blueMask & 0xFF00) >> 8); - bmi[offset + 10] = (byte)((blueMask & 0xFF0000) >> 16); - bmi[offset + 11] = (byte)((blueMask & 0xFF000000) >> 24); - break; - case 32: - redMask = 0xFF00; - greenMask = 0xFF0000; - blueMask = 0xFF000000; - /* big endian */ - bmi[offset] = (byte)((redMask & 0xFF000000) >> 24); - bmi[offset + 1] = (byte)((redMask & 0xFF0000) >> 16); - bmi[offset + 2] = (byte)((redMask & 0xFF00) >> 8); - bmi[offset + 3] = (byte)((redMask & 0xFF) >> 0); - bmi[offset + 4] = (byte)((greenMask & 0xFF000000) >> 24); - bmi[offset + 5] = (byte)((greenMask & 0xFF0000) >> 16); - bmi[offset + 6] = (byte)((greenMask & 0xFF00) >> 8); - bmi[offset + 7] = (byte)((greenMask & 0xFF) >> 0); - bmi[offset + 8] = (byte)((blueMask & 0xFF000000) >> 24); - bmi[offset + 9] = (byte)((blueMask & 0xFF0000) >> 16); - bmi[offset + 10] = (byte)((blueMask & 0xFF00) >> 8); - bmi[offset + 11] = (byte)((blueMask & 0xFF) >> 0); - break; - default: - SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); - } - } - } else { - for (int j = 0; j < rgbs.length; j++) { - bmi[offset] = (byte)rgbs[j].blue; - bmi[offset + 1] = (byte)rgbs[j].green; - bmi[offset + 2] = (byte)rgbs[j].red; - bmi[offset + 3] = 0; - offset += 4; - } - } - int /*long*/[] pBits = new int /*long*/[1]; - int /*long*/ hDib = OS.CreateDIBSection(0, bmi, OS.DIB_RGB_COLORS, pBits, 0, 0); - if (hDib == 0) SWT.error(SWT.ERROR_NO_HANDLES); - - /* Bitblt DDB into DIB */ - int /*long*/ hdcSource = OS.CreateCompatibleDC(hDC); - int /*long*/ hdcDest = OS.CreateCompatibleDC(hDC); - int /*long*/ hOldSrc = OS.SelectObject(hdcSource, hBitmap); - int /*long*/ hOldDest = OS.SelectObject(hdcDest, hDib); - OS.BitBlt(hdcDest, 0, 0, width, height, hdcSource, 0, 0, OS.SRCCOPY); - OS.SelectObject(hdcSource, hOldSrc); - OS.SelectObject(hdcDest, hOldDest); - OS.DeleteDC(hdcSource); - OS.DeleteDC(hdcDest); - - return hDib; -} - -int /*long*/ [] createGdipImage() { - switch (type) { - case SWT.BITMAP: { - if (alpha != -1 || alphaData != null || transparentPixel != -1) { - BITMAP bm = new BITMAP(); - OS.GetObject(handle, BITMAP.sizeof, bm); - int imgWidth = bm.bmWidth; - int imgHeight = bm.bmHeight; - int /*long*/ hDC = device.internal_new_GC(null); - int /*long*/ srcHdc = OS.CreateCompatibleDC(hDC); - int /*long*/ oldSrcBitmap = OS.SelectObject(srcHdc, handle); - int /*long*/ memHdc = OS.CreateCompatibleDC(hDC); - int /*long*/ memDib = createDIB(imgWidth, imgHeight, 32); - if (memDib == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int /*long*/ oldMemBitmap = OS.SelectObject(memHdc, memDib); - BITMAP dibBM = new BITMAP(); - OS.GetObject(memDib, BITMAP.sizeof, dibBM); - int sizeInBytes = dibBM.bmWidthBytes * dibBM.bmHeight; - OS.BitBlt(memHdc, 0, 0, imgWidth, imgHeight, srcHdc, 0, 0, OS.SRCCOPY); - byte red = 0, green = 0, blue = 0; - if (transparentPixel != -1) { - if (bm.bmBitsPixel <= 8) { - byte[] color = new byte[4]; - OS.GetDIBColorTable(srcHdc, transparentPixel, 1, color); - blue = color[0]; - green = color[1]; - red = color[2]; - } else { - switch (bm.bmBitsPixel) { - case 16: - int blueMask = 0x1F; - int blueShift = ImageData.getChannelShift(blueMask); - byte[] blues = ImageData.ANY_TO_EIGHT[ImageData.getChannelWidth(blueMask, blueShift)]; - blue = blues[(transparentPixel & blueMask) >> blueShift]; - int greenMask = 0x3E0; - int greenShift = ImageData.getChannelShift(greenMask); - byte[] greens = ImageData.ANY_TO_EIGHT[ImageData.getChannelWidth(greenMask, greenShift)]; - green = greens[(transparentPixel & greenMask) >> greenShift]; - int redMask = 0x7C00; - int redShift = ImageData.getChannelShift(redMask); - byte[] reds = ImageData.ANY_TO_EIGHT[ImageData.getChannelWidth(redMask, redShift)]; - red = reds[(transparentPixel & redMask) >> redShift]; - break; - case 24: - blue = (byte)((transparentPixel & 0xFF0000) >> 16); - green = (byte)((transparentPixel & 0xFF00) >> 8); - red = (byte)(transparentPixel & 0xFF); - break; - case 32: - blue = (byte)((transparentPixel & 0xFF000000) >>> 24); - green = (byte)((transparentPixel & 0xFF0000) >> 16); - red = (byte)((transparentPixel & 0xFF00) >> 8); - break; - } - } - } - OS.SelectObject(srcHdc, oldSrcBitmap); - OS.SelectObject(memHdc, oldMemBitmap); - OS.DeleteObject(srcHdc); - OS.DeleteObject(memHdc); - byte[] srcData = new byte[sizeInBytes]; - OS.MoveMemory(srcData, dibBM.bmBits, sizeInBytes); - OS.DeleteObject(memDib); - device.internal_dispose_GC(hDC, null); - if (alpha != -1) { - for (int y = 0, dp = 0; y < imgHeight; ++y) { - for (int x = 0; x < imgWidth; ++x) { - srcData[dp + 3] = (byte)alpha; - dp += 4; - } - } - } else if (alphaData != null) { - for (int y = 0, dp = 0, ap = 0; y < imgHeight; ++y) { - for (int x = 0; x < imgWidth; ++x) { - srcData[dp + 3] = alphaData[ap++]; - dp += 4; - } - } - } else if (transparentPixel != -1) { - for (int y = 0, dp = 0; y < imgHeight; ++y) { - for (int x = 0; x < imgWidth; ++x) { - if (srcData[dp] == blue && srcData[dp + 1] == green && srcData[dp + 2] == red) { - srcData[dp + 3] = (byte)0; - } else { - srcData[dp + 3] = (byte)0xFF; - } - dp += 4; - } - } - } - int /*long*/ hHeap = OS.GetProcessHeap(); - int /*long*/ pixels = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, srcData.length); - if (pixels == 0) SWT.error(SWT.ERROR_NO_HANDLES); - OS.MoveMemory(pixels, srcData, sizeInBytes); - return new int /*long*/ []{Gdip.Bitmap_new(imgWidth, imgHeight, dibBM.bmWidthBytes, Gdip.PixelFormat32bppARGB, pixels), pixels}; - } - return new int /*long*/ []{Gdip.Bitmap_new(handle, 0), 0}; - } - case SWT.ICON: { - /* - * Bug in GDI+. Creating a new GDI+ Bitmap from a HICON segment faults - * when the icon width is bigger than the icon height. The fix is to - * detect this and create a PixelFormat32bppARGB image instead. - */ - ICONINFO iconInfo = new ICONINFO(); - if (OS.IsWinCE) { - GetIconInfo(this, iconInfo); - } else { - OS.GetIconInfo(handle, iconInfo); - } - int /*long*/ hBitmap = iconInfo.hbmColor; - if (hBitmap == 0) hBitmap = iconInfo.hbmMask; - BITMAP bm = new BITMAP(); - OS.GetObject(hBitmap, BITMAP.sizeof, bm); - int imgWidth = bm.bmWidth; - int imgHeight = hBitmap == iconInfo.hbmMask ? bm.bmHeight / 2 : bm.bmHeight; - int /*long*/ img = 0, pixels = 0; - /* - * Bug in GDI+. Bitmap_new() segments fault if the image width - * is greater than the image height. - * - * Note that it also fails to generated an appropriate alpha - * channel when the icon depth is 32. - */ - if (imgWidth > imgHeight || bm.bmBitsPixel == 32) { - int /*long*/ hDC = device.internal_new_GC(null); - int /*long*/ srcHdc = OS.CreateCompatibleDC(hDC); - int /*long*/ oldSrcBitmap = OS.SelectObject(srcHdc, hBitmap); - int /*long*/ memHdc = OS.CreateCompatibleDC(hDC); - int /*long*/ memDib = createDIB(imgWidth, imgHeight, 32); - if (memDib == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int /*long*/ oldMemBitmap = OS.SelectObject(memHdc, memDib); - BITMAP dibBM = new BITMAP(); - OS.GetObject(memDib, BITMAP.sizeof, dibBM); - OS.BitBlt(memHdc, 0, 0, imgWidth, imgHeight, srcHdc, 0, hBitmap == iconInfo.hbmMask ? imgHeight : 0, OS.SRCCOPY); - OS.SelectObject(memHdc, oldMemBitmap); - OS.DeleteObject(memHdc); - byte[] srcData = new byte[dibBM.bmWidthBytes * dibBM.bmHeight]; - OS.MoveMemory(srcData, dibBM.bmBits, srcData.length); - OS.DeleteObject(memDib); - OS.SelectObject(srcHdc, iconInfo.hbmMask); - for (int y = 0, dp = 3; y < imgHeight; ++y) { - for (int x = 0; x < imgWidth; ++x) { - if (srcData[dp] == 0) { - if (OS.GetPixel(srcHdc, x, y) != 0) { - srcData[dp] = (byte)0; - } else { - srcData[dp] = (byte)0xFF; - } - } - dp += 4; - } - } - OS.SelectObject(srcHdc, oldSrcBitmap); - OS.DeleteObject(srcHdc); - device.internal_dispose_GC(hDC, null); - int /*long*/ hHeap = OS.GetProcessHeap(); - pixels = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, srcData.length); - if (pixels == 0) SWT.error(SWT.ERROR_NO_HANDLES); - OS.MoveMemory(pixels, srcData, srcData.length); - img = Gdip.Bitmap_new(imgWidth, imgHeight, dibBM.bmWidthBytes, Gdip.PixelFormat32bppARGB, pixels); - } else { - img = Gdip.Bitmap_new(handle); - } - if (iconInfo.hbmColor != 0) OS.DeleteObject(iconInfo.hbmColor); - if (iconInfo.hbmMask != 0) OS.DeleteObject(iconInfo.hbmMask); - return new int /*long*/ []{img, pixels}; - } - default: SWT.error(SWT.ERROR_INVALID_IMAGE); - } - return null; -} - -void destroy () { - if (memGC != null) memGC.dispose(); - if (type == SWT.ICON) { - if (OS.IsWinCE) data = null; - OS.DestroyIcon (handle); - } else { - OS.DeleteObject (handle); - } - 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; -} - -/** - * 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; - - /* Get the HDC for the device */ - int /*long*/ hDC = device.internal_new_GC(null); - - /* Compute the background color */ - BITMAP bm = new BITMAP(); - OS.GetObject(handle, BITMAP.sizeof, bm); - int /*long*/ hdcMem = OS.CreateCompatibleDC(hDC); - int /*long*/ hOldObject = OS.SelectObject(hdcMem, handle); - int red = 0, green = 0, blue = 0; - if (bm.bmBitsPixel <= 8) { - if (OS.IsWinCE) { - byte[] pBits = new byte[1]; - OS.MoveMemory(pBits, bm.bmBits, 1); - byte oldValue = pBits[0]; - int mask = (0xFF << (8 - bm.bmBitsPixel)) & 0x00FF; - pBits[0] = (byte)((transparentPixel << (8 - bm.bmBitsPixel)) | (pBits[0] & ~mask)); - OS.MoveMemory(bm.bmBits, pBits, 1); - int color = OS.GetPixel(hdcMem, 0, 0); - pBits[0] = oldValue; - OS.MoveMemory(bm.bmBits, pBits, 1); - blue = (color & 0xFF0000) >> 16; - green = (color & 0xFF00) >> 8; - red = color & 0xFF; - } else { - byte[] color = new byte[4]; - OS.GetDIBColorTable(hdcMem, transparentPixel, 1, color); - blue = color[0] & 0xFF; - green = color[1] & 0xFF; - red = color[2] & 0xFF; - } - } else { - switch (bm.bmBitsPixel) { - case 16: - blue = (transparentPixel & 0x1F) << 3; - green = (transparentPixel & 0x3E0) >> 2; - red = (transparentPixel & 0x7C00) >> 7; - break; - case 24: - blue = (transparentPixel & 0xFF0000) >> 16; - green = (transparentPixel & 0xFF00) >> 8; - red = transparentPixel & 0xFF; - break; - case 32: - blue = (transparentPixel & 0xFF000000) >>> 24; - green = (transparentPixel & 0xFF0000) >> 16; - red = (transparentPixel & 0xFF00) >> 8; - break; - default: - return null; - } - } - OS.SelectObject(hdcMem, hOldObject); - OS.DeleteDC(hdcMem); - - /* Release the HDC for the device */ - device.internal_dispose_GC(hDC, null); - return Color.win32_new(device, (blue << 16) | (green << 8) | red); -} - -/** - * 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); - } - switch (type) { - case SWT.BITMAP: - BITMAP bm = new BITMAP(); - OS.GetObject(handle, BITMAP.sizeof, bm); - return new Rectangle(0, 0, width = bm.bmWidth, height = bm.bmHeight); - case SWT.ICON: - if (OS.IsWinCE) { - return new Rectangle(0, 0, width = data.width, height = data.height); - } else { - ICONINFO info = new ICONINFO(); - OS.GetIconInfo(handle, info); - int /*long*/ hBitmap = info.hbmColor; - if (hBitmap == 0) hBitmap = info.hbmMask; - bm = new BITMAP(); - OS.GetObject(hBitmap, BITMAP.sizeof, bm); - if (hBitmap == info.hbmMask) bm.bmHeight /= 2; - if (info.hbmColor != 0) OS.DeleteObject(info.hbmColor); - if (info.hbmMask != 0) OS.DeleteObject(info.hbmMask); - return new Rectangle(0, 0, width = bm.bmWidth, height = bm.bmHeight); - } - default: - SWT.error(SWT.ERROR_INVALID_IMAGE); - return null; - } -} - -/** - * 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); - BITMAP bm; - int depth, width, height; - switch (type) { - case SWT.ICON: { - if (OS.IsWinCE) return data; - ICONINFO info = new ICONINFO(); - if (OS.IsWinCE) SWT.error(SWT.ERROR_NOT_IMPLEMENTED); - OS.GetIconInfo(handle, info); - /* Get the basic BITMAP information */ - int /*long*/ hBitmap = info.hbmColor; - if (hBitmap == 0) hBitmap = info.hbmMask; - bm = new BITMAP(); - OS.GetObject(hBitmap, BITMAP.sizeof, bm); - depth = bm.bmPlanes * bm.bmBitsPixel; - width = bm.bmWidth; - if (hBitmap == info.hbmMask) bm.bmHeight /= 2; - height = bm.bmHeight; - int numColors = 0; - if (depth <= 8) numColors = 1 << depth; - /* Create the BITMAPINFO */ - BITMAPINFOHEADER bmiHeader = new BITMAPINFOHEADER(); - bmiHeader.biSize = BITMAPINFOHEADER.sizeof; - bmiHeader.biWidth = width; - bmiHeader.biHeight = -height; - bmiHeader.biPlanes = 1; - bmiHeader.biBitCount = (short)depth; - bmiHeader.biCompression = OS.BI_RGB; - byte[] bmi = new byte[BITMAPINFOHEADER.sizeof + numColors * 4]; - OS.MoveMemory(bmi, bmiHeader, BITMAPINFOHEADER.sizeof); - - /* Get the HDC for the device */ - int /*long*/ hDC = device.internal_new_GC(null); - - /* Create the DC and select the bitmap */ - int /*long*/ hBitmapDC = OS.CreateCompatibleDC(hDC); - int /*long*/ hOldBitmap = OS.SelectObject(hBitmapDC, hBitmap); - /* Select the palette if necessary */ - int /*long*/ oldPalette = 0; - if (depth <= 8) { - int /*long*/ hPalette = device.hPalette; - if (hPalette != 0) { - oldPalette = OS.SelectPalette(hBitmapDC, hPalette, false); - OS.RealizePalette(hBitmapDC); - } - } - /* Find the size of the image and allocate data */ - int imageSize; - /* Call with null lpBits to get the image size */ - if (OS.IsWinCE) SWT.error(SWT.ERROR_NOT_IMPLEMENTED); - OS.GetDIBits(hBitmapDC, hBitmap, 0, height, 0, bmi, OS.DIB_RGB_COLORS); - OS.MoveMemory(bmiHeader, bmi, BITMAPINFOHEADER.sizeof); - imageSize = bmiHeader.biSizeImage; - byte[] data = new byte[imageSize]; - /* Get the bitmap data */ - int /*long*/ hHeap = OS.GetProcessHeap(); - int /*long*/ lpvBits = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, imageSize); - if (lpvBits == 0) SWT.error(SWT.ERROR_NO_HANDLES); - if (OS.IsWinCE) SWT.error(SWT.ERROR_NOT_IMPLEMENTED); - OS.GetDIBits(hBitmapDC, hBitmap, 0, height, lpvBits, bmi, OS.DIB_RGB_COLORS); - OS.MoveMemory(data, lpvBits, imageSize); - /* Calculate the palette */ - PaletteData palette = null; - if (depth <= 8) { - RGB[] rgbs = new RGB[numColors]; - int srcIndex = 40; - for (int i = 0; i < numColors; i++) { - rgbs[i] = new RGB(bmi[srcIndex + 2] & 0xFF, bmi[srcIndex + 1] & 0xFF, bmi[srcIndex] & 0xFF); - srcIndex += 4; - } - palette = new PaletteData(rgbs); - } else if (depth == 16) { - palette = new PaletteData(0x7C00, 0x3E0, 0x1F); - } else if (depth == 24) { - palette = new PaletteData(0xFF, 0xFF00, 0xFF0000); - } else if (depth == 32) { - palette = new PaletteData(0xFF00, 0xFF0000, 0xFF000000); - } else { - SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); - } - - /* Do the mask */ - byte [] maskData = null; - if (info.hbmColor == 0) { - /* Do the bottom half of the mask */ - maskData = new byte[imageSize]; - if (OS.IsWinCE) SWT.error(SWT.ERROR_NOT_IMPLEMENTED); - OS.GetDIBits(hBitmapDC, hBitmap, height, height, lpvBits, bmi, OS.DIB_RGB_COLORS); - OS.MoveMemory(maskData, lpvBits, imageSize); - } else { - /* Do the entire mask */ - /* Create the BITMAPINFO */ - bmiHeader = new BITMAPINFOHEADER(); - bmiHeader.biSize = BITMAPINFOHEADER.sizeof; - bmiHeader.biWidth = width; - bmiHeader.biHeight = -height; - bmiHeader.biPlanes = 1; - bmiHeader.biBitCount = 1; - bmiHeader.biCompression = OS.BI_RGB; - bmi = new byte[BITMAPINFOHEADER.sizeof + 8]; - OS.MoveMemory(bmi, bmiHeader, BITMAPINFOHEADER.sizeof); - - /* First color black, second color white */ - int offset = BITMAPINFOHEADER.sizeof; - bmi[offset + 4] = bmi[offset + 5] = bmi[offset + 6] = (byte)0xFF; - bmi[offset + 7] = 0; - OS.SelectObject(hBitmapDC, info.hbmMask); - /* Call with null lpBits to get the image size */ - if (OS.IsWinCE) SWT.error(SWT.ERROR_NOT_IMPLEMENTED); - OS.GetDIBits(hBitmapDC, info.hbmMask, 0, height, 0, bmi, OS.DIB_RGB_COLORS); - OS.MoveMemory(bmiHeader, bmi, BITMAPINFOHEADER.sizeof); - imageSize = bmiHeader.biSizeImage; - maskData = new byte[imageSize]; - int /*long*/ lpvMaskBits = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, imageSize); - if (lpvMaskBits == 0) SWT.error(SWT.ERROR_NO_HANDLES); - if (OS.IsWinCE) SWT.error(SWT.ERROR_NOT_IMPLEMENTED); - OS.GetDIBits(hBitmapDC, info.hbmMask, 0, height, lpvMaskBits, bmi, OS.DIB_RGB_COLORS); - OS.MoveMemory(maskData, lpvMaskBits, imageSize); - OS.HeapFree(hHeap, 0, lpvMaskBits); - /* Loop to invert the mask */ - for (int i = 0; i < maskData.length; i++) { - maskData[i] ^= -1; - } - /* Make sure mask scanlinePad is 2 */ - int maskPad; - int bpl = imageSize / height; - for (maskPad = 1; maskPad < 128; maskPad++) { - int calcBpl = (((width + 7) / 8) + (maskPad - 1)) / maskPad * maskPad; - if (calcBpl == bpl) break; - } - maskData = ImageData.convertPad(maskData, width, height, 1, maskPad, 2); - } - /* Clean up */ - OS.HeapFree(hHeap, 0, lpvBits); - OS.SelectObject(hBitmapDC, hOldBitmap); - if (oldPalette != 0) { - OS.SelectPalette(hBitmapDC, oldPalette, false); - OS.RealizePalette(hBitmapDC); - } - OS.DeleteDC(hBitmapDC); - - /* Release the HDC for the device */ - device.internal_dispose_GC(hDC, null); - - if (info.hbmColor != 0) OS.DeleteObject(info.hbmColor); - if (info.hbmMask != 0) OS.DeleteObject(info.hbmMask); - /* Construct and return the ImageData */ - ImageData imageData = new ImageData(width, height, depth, palette, 4, data); - imageData.maskData = maskData; - imageData.maskPad = 2; - return imageData; - } - case SWT.BITMAP: { - /* Get the basic BITMAP information */ - bm = new BITMAP(); - OS.GetObject(handle, BITMAP.sizeof, bm); - depth = bm.bmPlanes * bm.bmBitsPixel; - width = bm.bmWidth; - height = bm.bmHeight; - /* Find out whether this is a DIB or a DDB. */ - boolean isDib = (bm.bmBits != 0); - /* Get the HDC for the device */ - int /*long*/ hDC = device.internal_new_GC(null); - - /* - * Feature in WinCE. GetDIBits is not available in WinCE. The - * workaround is to create a temporary DIB from the DDB and use - * the bmBits field of DIBSECTION to retrieve the image data. - */ - int /*long*/ handle = this.handle; - if (OS.IsWinCE) { - if (!isDib) { - boolean mustRestore = false; - if (memGC != null && !memGC.isDisposed()) { - memGC.flush (); - mustRestore = true; - GCData data = memGC.data; - if (data.hNullBitmap != 0) { - OS.SelectObject(memGC.handle, data.hNullBitmap); - data.hNullBitmap = 0; - } - } - handle = createDIBFromDDB(hDC, this.handle, width, height); - if (mustRestore) { - int /*long*/ hOldBitmap = OS.SelectObject(memGC.handle, this.handle); - memGC.data.hNullBitmap = hOldBitmap; - } - isDib = true; - } - } - DIBSECTION dib = null; - if (isDib) { - dib = new DIBSECTION(); - OS.GetObject(handle, DIBSECTION.sizeof, dib); - } - /* Calculate number of colors */ - int numColors = 0; - if (depth <= 8) { - if (isDib) { - numColors = dib.biClrUsed; - } else { - numColors = 1 << depth; - } - } - /* Create the BITMAPINFO */ - byte[] bmi = null; - BITMAPINFOHEADER bmiHeader = null; - if (!isDib) { - bmiHeader = new BITMAPINFOHEADER(); - bmiHeader.biSize = BITMAPINFOHEADER.sizeof; - bmiHeader.biWidth = width; - bmiHeader.biHeight = -height; - bmiHeader.biPlanes = 1; - bmiHeader.biBitCount = (short)depth; - bmiHeader.biCompression = OS.BI_RGB; - bmi = new byte[BITMAPINFOHEADER.sizeof + numColors * 4]; - OS.MoveMemory(bmi, bmiHeader, BITMAPINFOHEADER.sizeof); - } - - /* Create the DC and select the bitmap */ - int /*long*/ hBitmapDC = OS.CreateCompatibleDC(hDC); - int /*long*/ hOldBitmap = OS.SelectObject(hBitmapDC, handle); - /* Select the palette if necessary */ - int /*long*/ oldPalette = 0; - if (!isDib && depth <= 8) { - int /*long*/ hPalette = device.hPalette; - if (hPalette != 0) { - oldPalette = OS.SelectPalette(hBitmapDC, hPalette, false); - OS.RealizePalette(hBitmapDC); - } - } - /* Find the size of the image and allocate data */ - int imageSize; - if (isDib) { - imageSize = dib.biSizeImage; - } else { - /* Call with null lpBits to get the image size */ - if (OS.IsWinCE) SWT.error(SWT.ERROR_NOT_IMPLEMENTED); - OS.GetDIBits(hBitmapDC, handle, 0, height, 0, bmi, OS.DIB_RGB_COLORS); - OS.MoveMemory(bmiHeader, bmi, BITMAPINFOHEADER.sizeof); - imageSize = bmiHeader.biSizeImage; - } - byte[] data = new byte[imageSize]; - /* Get the bitmap data */ - if (isDib) { - if (OS.IsWinCE && this.handle != handle) { - /* get image data from the temporary DIB */ - OS.MoveMemory(data, dib.bmBits, imageSize); - } else { - OS.MoveMemory(data, bm.bmBits, imageSize); - } - } else { - int /*long*/ hHeap = OS.GetProcessHeap(); - int /*long*/ lpvBits = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, imageSize); - if (lpvBits == 0) SWT.error(SWT.ERROR_NO_HANDLES); - if (OS.IsWinCE) SWT.error(SWT.ERROR_NOT_IMPLEMENTED); - OS.GetDIBits(hBitmapDC, handle, 0, height, lpvBits, bmi, OS.DIB_RGB_COLORS); - OS.MoveMemory(data, lpvBits, imageSize); - OS.HeapFree(hHeap, 0, lpvBits); - } - /* Calculate the palette */ - PaletteData palette = null; - if (depth <= 8) { - RGB[] rgbs = new RGB[numColors]; - if (isDib) { - if (OS.IsWinCE) { - /* - * Feature on WinCE. GetDIBColorTable is not supported. - * The workaround is to set a pixel to the desired - * palette index and use getPixel to get the corresponding - * RGB value. - */ - int red = 0, green = 0, blue = 0; - byte[] pBits = new byte[1]; - OS.MoveMemory(pBits, bm.bmBits, 1); - byte oldValue = pBits[0]; - int mask = (0xFF << (8 - bm.bmBitsPixel)) & 0x00FF; - for (int i = 0; i < numColors; i++) { - pBits[0] = (byte)((i << (8 - bm.bmBitsPixel)) | (pBits[0] & ~mask)); - OS.MoveMemory(bm.bmBits, pBits, 1); - int color = OS.GetPixel(hBitmapDC, 0, 0); - blue = (color & 0xFF0000) >> 16; - green = (color & 0xFF00) >> 8; - red = color & 0xFF; - rgbs[i] = new RGB(red, green, blue); - } - pBits[0] = oldValue; - OS.MoveMemory(bm.bmBits, pBits, 1); - } else { - byte[] colors = new byte[numColors * 4]; - OS.GetDIBColorTable(hBitmapDC, 0, numColors, colors); - int colorIndex = 0; - for (int i = 0; i < rgbs.length; i++) { - rgbs[i] = new RGB(colors[colorIndex + 2] & 0xFF, colors[colorIndex + 1] & 0xFF, colors[colorIndex] & 0xFF); - colorIndex += 4; - } - } - } else { - int srcIndex = BITMAPINFOHEADER.sizeof; - for (int i = 0; i < numColors; i++) { - rgbs[i] = new RGB(bmi[srcIndex + 2] & 0xFF, bmi[srcIndex + 1] & 0xFF, bmi[srcIndex] & 0xFF); - srcIndex += 4; - } - } - palette = new PaletteData(rgbs); - } else if (depth == 16) { - palette = new PaletteData(0x7C00, 0x3E0, 0x1F); - } else if (depth == 24) { - palette = new PaletteData(0xFF, 0xFF00, 0xFF0000); - } else if (depth == 32) { - palette = new PaletteData(0xFF00, 0xFF0000, 0xFF000000); - } else { - SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); - } - /* Clean up */ - OS.SelectObject(hBitmapDC, hOldBitmap); - if (oldPalette != 0) { - OS.SelectPalette(hBitmapDC, oldPalette, false); - OS.RealizePalette(hBitmapDC); - } - if (OS.IsWinCE) { - if (handle != this.handle) { - /* free temporary DIB */ - OS.DeleteObject (handle); - } - } - OS.DeleteDC(hBitmapDC); - - /* Release the HDC for the device */ - device.internal_dispose_GC(hDC, null); - - /* Construct and return the ImageData */ - ImageData imageData = new ImageData(width, height, depth, palette, 4, data); - imageData.transparentPixel = this.transparentPixel; - imageData.alpha = alpha; - if (alpha == -1 && alphaData != null) { - imageData.alphaData = new byte[alphaData.length]; - System.arraycopy(alphaData, 0, imageData.alphaData, 0, alphaData.length); - } - return imageData; - } - default: - SWT.error(SWT.ERROR_INVALID_IMAGE); - return null; - } -} - -/** - * 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 (int)/*64*/handle; -} - -void init(int width, int height) { - if (width <= 0 || height <= 0) { - SWT.error (SWT.ERROR_INVALID_ARGUMENT); - } - type = SWT.BITMAP; - int /*long*/ hDC = device.internal_new_GC(null); - handle = OS.CreateCompatibleBitmap(hDC, width, height); - /* - * Feature in Windows. CreateCompatibleBitmap() may fail - * for large images. The fix is to create a DIB section - * in that case. - */ - if (handle == 0) { - int bits = OS.GetDeviceCaps(hDC, OS.BITSPIXEL); - int planes = OS.GetDeviceCaps(hDC, OS.PLANES); - int depth = bits * planes; - if (depth < 16) depth = 16; - handle = createDIB(width, height, depth); - } - if (handle != 0) { - int /*long*/ memDC = OS.CreateCompatibleDC(hDC); - int /*long*/ hOldBitmap = OS.SelectObject(memDC, handle); - OS.PatBlt(memDC, 0, 0, width, height, OS.PATCOPY); - OS.SelectObject(memDC, hOldBitmap); - OS.DeleteDC(memDC); - } - device.internal_dispose_GC(hDC, null); - if (handle == 0) { - SWT.error(SWT.ERROR_NO_HANDLES, null, device.getLastError()); - } -} - -static int /*long*/ createDIB(int width, int height, int depth) { - BITMAPINFOHEADER bmiHeader = new BITMAPINFOHEADER(); - bmiHeader.biSize = BITMAPINFOHEADER.sizeof; - bmiHeader.biWidth = width; - bmiHeader.biHeight = -height; - bmiHeader.biPlanes = 1; - bmiHeader.biBitCount = (short)depth; - if (OS.IsWinCE) bmiHeader.biCompression = OS.BI_BITFIELDS; - else bmiHeader.biCompression = OS.BI_RGB; - byte[] bmi = new byte[BITMAPINFOHEADER.sizeof + (OS.IsWinCE ? 12 : 0)]; - OS.MoveMemory(bmi, bmiHeader, BITMAPINFOHEADER.sizeof); - /* Set the rgb colors into the bitmap info */ - if (OS.IsWinCE) { - int redMask = 0xFF00; - int greenMask = 0xFF0000; - int blueMask = 0xFF000000; - /* big endian */ - int offset = BITMAPINFOHEADER.sizeof; - bmi[offset] = (byte)((redMask & 0xFF000000) >> 24); - bmi[offset + 1] = (byte)((redMask & 0xFF0000) >> 16); - bmi[offset + 2] = (byte)((redMask & 0xFF00) >> 8); - bmi[offset + 3] = (byte)((redMask & 0xFF) >> 0); - bmi[offset + 4] = (byte)((greenMask & 0xFF000000) >> 24); - bmi[offset + 5] = (byte)((greenMask & 0xFF0000) >> 16); - bmi[offset + 6] = (byte)((greenMask & 0xFF00) >> 8); - bmi[offset + 7] = (byte)((greenMask & 0xFF) >> 0); - bmi[offset + 8] = (byte)((blueMask & 0xFF000000) >> 24); - bmi[offset + 9] = (byte)((blueMask & 0xFF0000) >> 16); - bmi[offset + 10] = (byte)((blueMask & 0xFF00) >> 8); - bmi[offset + 11] = (byte)((blueMask & 0xFF) >> 0); - } - - int /*long*/[] pBits = new int /*long*/[1]; - return OS.CreateDIBSection(0, bmi, OS.DIB_RGB_COLORS, pBits, 0, 0); -} - -/** - * Feature in WinCE. GetIconInfo is not available in WinCE. - * The workaround is to cache the object ImageData for images - * of type SWT.ICON. The bitmaps hbmMask and hbmColor can then - * be reconstructed by using our version of getIconInfo. - * This function takes an ICONINFO object and sets the fields - * hbmMask and hbmColor with the corresponding bitmaps it has - * created. - * Note. These bitmaps must be freed - as they would have to be - * if the regular GetIconInfo had been used. - */ -static void GetIconInfo(Image image, ICONINFO info) { - int /*long*/ [] result = init(image.device, null, image.data); - info.hbmColor = result[0]; - info.hbmMask = result[1]; -} - -static int /*long*/ [] init(Device device, Image image, ImageData i) { - /* - * BUG in Windows 98: - * A monochrome DIBSection will display as solid black - * on Windows 98 machines, even though it contains the - * correct data. The fix is to convert 1-bit ImageData - * into 4-bit ImageData before creating the image. - */ - /* Windows does not support 2-bit images. Convert to 4-bit image. */ - if ((OS.IsWin95 && i.depth == 1 && i.getTransparencyType() != SWT.TRANSPARENCY_MASK) || i.depth == 2) { - ImageData img = new ImageData(i.width, i.height, 4, i.palette); - ImageData.blit(ImageData.BLIT_SRC, - i.data, i.depth, i.bytesPerLine, i.getByteOrder(), 0, 0, i.width, i.height, null, null, null, - ImageData.ALPHA_OPAQUE, null, 0, 0, 0, - img.data, img.depth, img.bytesPerLine, i.getByteOrder(), 0, 0, img.width, img.height, null, null, null, - false, false); - img.transparentPixel = i.transparentPixel; - img.maskPad = i.maskPad; - img.maskData = i.maskData; - img.alpha = i.alpha; - img.alphaData = i.alphaData; - i = img; - } - /* - * Windows supports 16-bit mask of (0x7C00, 0x3E0, 0x1F), - * 24-bit mask of (0xFF0000, 0xFF00, 0xFF) and 32-bit mask - * (0x00FF0000, 0x0000FF00, 0x000000FF) as documented in - * MSDN BITMAPINFOHEADER. Make sure the image is - * Windows-supported. - */ - /* - * Note on WinCE. CreateDIBSection requires the biCompression - * field of the BITMAPINFOHEADER to be set to BI_BITFIELDS for - * 16 and 32 bit direct images (see MSDN for CreateDIBSection). - * In this case, the color mask can be set to any value. For - * consistency, it is set to the same mask used by non WinCE - * platforms in BI_RGB mode. - */ - if (i.palette.isDirect) { - final PaletteData palette = i.palette; - final int redMask = palette.redMask; - final int greenMask = palette.greenMask; - final int blueMask = palette.blueMask; - int newDepth = i.depth; - int newOrder = ImageData.MSB_FIRST; - PaletteData newPalette = null; - - switch (i.depth) { - case 8: - newDepth = 16; - newOrder = ImageData.LSB_FIRST; - newPalette = new PaletteData(0x7C00, 0x3E0, 0x1F); - break; - case 16: - newOrder = ImageData.LSB_FIRST; - if (!(redMask == 0x7C00 && greenMask == 0x3E0 && blueMask == 0x1F)) { - newPalette = new PaletteData(0x7C00, 0x3E0, 0x1F); - } - break; - case 24: - if (!(redMask == 0xFF && greenMask == 0xFF00 && blueMask == 0xFF0000)) { - newPalette = new PaletteData(0xFF, 0xFF00, 0xFF0000); - } - break; - case 32: - if (!(redMask == 0xFF00 && greenMask == 0xFF0000 && blueMask == 0xFF000000)) { - newPalette = new PaletteData(0xFF00, 0xFF0000, 0xFF000000); - } - break; - default: - SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); - } - if (newPalette != null) { - ImageData img = new ImageData(i.width, i.height, newDepth, newPalette); - ImageData.blit(ImageData.BLIT_SRC, - i.data, i.depth, i.bytesPerLine, i.getByteOrder(), 0, 0, i.width, i.height, redMask, greenMask, blueMask, - ImageData.ALPHA_OPAQUE, null, 0, 0, 0, - img.data, img.depth, img.bytesPerLine, newOrder, 0, 0, img.width, img.height, newPalette.redMask, newPalette.greenMask, newPalette.blueMask, - false, false); - if (i.transparentPixel != -1) { - img.transparentPixel = newPalette.getPixel(palette.getRGB(i.transparentPixel)); - } - img.maskPad = i.maskPad; - img.maskData = i.maskData; - img.alpha = i.alpha; - img.alphaData = i.alphaData; - i = img; - } - } - /* Construct bitmap info header by hand */ - RGB[] rgbs = i.palette.getRGBs(); - boolean useBitfields = OS.IsWinCE && (i.depth == 16 || i.depth == 32); - BITMAPINFOHEADER bmiHeader = new BITMAPINFOHEADER(); - bmiHeader.biSize = BITMAPINFOHEADER.sizeof; - bmiHeader.biWidth = i.width; - bmiHeader.biHeight = -i.height; - bmiHeader.biPlanes = 1; - bmiHeader.biBitCount = (short)i.depth; - if (useBitfields) bmiHeader.biCompression = OS.BI_BITFIELDS; - else bmiHeader.biCompression = OS.BI_RGB; - bmiHeader.biClrUsed = rgbs == null ? 0 : rgbs.length; - byte[] bmi; - if (i.palette.isDirect) - bmi = new byte[BITMAPINFOHEADER.sizeof + (useBitfields ? 12 : 0)]; - else - bmi = new byte[BITMAPINFOHEADER.sizeof + rgbs.length * 4]; - OS.MoveMemory(bmi, bmiHeader, BITMAPINFOHEADER.sizeof); - /* Set the rgb colors into the bitmap info */ - int offset = BITMAPINFOHEADER.sizeof; - if (i.palette.isDirect) { - if (useBitfields) { - PaletteData palette = i.palette; - int redMask = palette.redMask; - int greenMask = palette.greenMask; - int blueMask = palette.blueMask; - /* - * The color masks must be written based on the - * endianness of the ImageData. - */ - if (i.getByteOrder() == ImageData.LSB_FIRST) { - bmi[offset] = (byte)((redMask & 0xFF) >> 0); - bmi[offset + 1] = (byte)((redMask & 0xFF00) >> 8); - bmi[offset + 2] = (byte)((redMask & 0xFF0000) >> 16); - bmi[offset + 3] = (byte)((redMask & 0xFF000000) >> 24); - bmi[offset + 4] = (byte)((greenMask & 0xFF) >> 0); - bmi[offset + 5] = (byte)((greenMask & 0xFF00) >> 8); - bmi[offset + 6] = (byte)((greenMask & 0xFF0000) >> 16); - bmi[offset + 7] = (byte)((greenMask & 0xFF000000) >> 24); - bmi[offset + 8] = (byte)((blueMask & 0xFF) >> 0); - bmi[offset + 9] = (byte)((blueMask & 0xFF00) >> 8); - bmi[offset + 10] = (byte)((blueMask & 0xFF0000) >> 16); - bmi[offset + 11] = (byte)((blueMask & 0xFF000000) >> 24); - } else { - bmi[offset] = (byte)((redMask & 0xFF000000) >> 24); - bmi[offset + 1] = (byte)((redMask & 0xFF0000) >> 16); - bmi[offset + 2] = (byte)((redMask & 0xFF00) >> 8); - bmi[offset + 3] = (byte)((redMask & 0xFF) >> 0); - bmi[offset + 4] = (byte)((greenMask & 0xFF000000) >> 24); - bmi[offset + 5] = (byte)((greenMask & 0xFF0000) >> 16); - bmi[offset + 6] = (byte)((greenMask & 0xFF00) >> 8); - bmi[offset + 7] = (byte)((greenMask & 0xFF) >> 0); - bmi[offset + 8] = (byte)((blueMask & 0xFF000000) >> 24); - bmi[offset + 9] = (byte)((blueMask & 0xFF0000) >> 16); - bmi[offset + 10] = (byte)((blueMask & 0xFF00) >> 8); - bmi[offset + 11] = (byte)((blueMask & 0xFF) >> 0); - } - } - } else { - for (int j = 0; j < rgbs.length; j++) { - bmi[offset] = (byte)rgbs[j].blue; - bmi[offset + 1] = (byte)rgbs[j].green; - bmi[offset + 2] = (byte)rgbs[j].red; - bmi[offset + 3] = 0; - offset += 4; - } - } - int /*long*/[] pBits = new int /*long*/[1]; - int /*long*/ hDib = OS.CreateDIBSection(0, bmi, OS.DIB_RGB_COLORS, pBits, 0, 0); - if (hDib == 0) SWT.error(SWT.ERROR_NO_HANDLES); - /* In case of a scanline pad other than 4, do the work to convert it */ - byte[] data = i.data; - if (i.scanlinePad != 4 && (i.bytesPerLine % 4 != 0)) { - data = ImageData.convertPad(data, i.width, i.height, i.depth, i.scanlinePad, 4); - } - OS.MoveMemory(pBits[0], data, data.length); - - int /*long*/ [] result = null; - if (i.getTransparencyType() == SWT.TRANSPARENCY_MASK) { - /* Get the HDC for the device */ - int /*long*/ hDC = device.internal_new_GC(null); - - /* Create the color bitmap */ - int /*long*/ hdcSrc = OS.CreateCompatibleDC(hDC); - OS.SelectObject(hdcSrc, hDib); - int /*long*/ hBitmap = OS.CreateCompatibleBitmap(hDC, i.width, i.height); - if (hBitmap == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int /*long*/ hdcDest = OS.CreateCompatibleDC(hDC); - OS.SelectObject(hdcDest, hBitmap); - OS.BitBlt(hdcDest, 0, 0, i.width, i.height, hdcSrc, 0, 0, OS.SRCCOPY); - - /* Release the HDC for the device */ - device.internal_dispose_GC(hDC, null); - - /* Create the mask. Windows requires icon masks to have a scanline pad of 2. */ - byte[] maskData = ImageData.convertPad(i.maskData, i.width, i.height, 1, i.maskPad, 2); - int /*long*/ hMask = OS.CreateBitmap(i.width, i.height, 1, 1, maskData); - if (hMask == 0) SWT.error(SWT.ERROR_NO_HANDLES); - OS.SelectObject(hdcSrc, hMask); - OS.PatBlt(hdcSrc, 0, 0, i.width, i.height, OS.DSTINVERT); - OS.DeleteDC(hdcSrc); - OS.DeleteDC(hdcDest); - OS.DeleteObject(hDib); - - if (image == null) { - result = new int /*long*/ []{hBitmap, hMask}; - } else { - /* Create the icon */ - ICONINFO info = new ICONINFO(); - info.fIcon = true; - info.hbmColor = hBitmap; - info.hbmMask = hMask; - int /*long*/ hIcon = OS.CreateIconIndirect(info); - if (hIcon == 0) SWT.error(SWT.ERROR_NO_HANDLES); - OS.DeleteObject(hBitmap); - OS.DeleteObject(hMask); - image.handle = hIcon; - image.type = SWT.ICON; - if (OS.IsWinCE) image.data = i; - } - } else { - if (image == null) { - result = new int /*long*/ []{hDib}; - } else { - image.handle = hDib; - image.type = SWT.BITMAP; - image.transparentPixel = i.transparentPixel; - if (image.transparentPixel == -1) { - image.alpha = i.alpha; - if (i.alpha == -1 && i.alphaData != null) { - int length = i.alphaData.length; - image.alphaData = new byte[length]; - System.arraycopy(i.alphaData, 0, image.alphaData, 0, length); - } - } - } - } - return result; -} - -static int /*long*/ [] init(Device device, Image image, ImageData source, ImageData mask) { - /* Create a temporary image and locate the black pixel */ - ImageData imageData; - int blackIndex = 0; - if (source.palette.isDirect) { - imageData = new ImageData(source.width, source.height, source.depth, source.palette); - } else { - RGB black = new RGB(0, 0, 0); - RGB[] rgbs = source.getRGBs(); - if (source.transparentPixel != -1) { - /* - * The source had transparency, so we can use the transparent pixel - * for black. - */ - RGB[] newRGBs = new RGB[rgbs.length]; - System.arraycopy(rgbs, 0, newRGBs, 0, rgbs.length); - if (source.transparentPixel >= newRGBs.length) { - /* Grow the palette with black */ - rgbs = new RGB[source.transparentPixel + 1]; - System.arraycopy(newRGBs, 0, rgbs, 0, newRGBs.length); - for (int i = newRGBs.length; i <= source.transparentPixel; i++) { - rgbs[i] = new RGB(0, 0, 0); - } - } else { - newRGBs[source.transparentPixel] = black; - rgbs = newRGBs; - } - blackIndex = source.transparentPixel; - imageData = new ImageData(source.width, source.height, source.depth, new PaletteData(rgbs)); - } else { - while (blackIndex < rgbs.length) { - if (rgbs[blackIndex].equals(black)) break; - blackIndex++; - } - if (blackIndex == rgbs.length) { - /* - * We didn't find black in the palette, and there is no transparent - * pixel we can use. - */ - if ((1 << source.depth) > rgbs.length) { - /* We can grow the palette and add black */ - RGB[] newRGBs = new RGB[rgbs.length + 1]; - System.arraycopy(rgbs, 0, newRGBs, 0, rgbs.length); - newRGBs[rgbs.length] = black; - rgbs = newRGBs; - } else { - /* No room to grow the palette */ - blackIndex = -1; - } - } - imageData = new ImageData(source.width, source.height, source.depth, new PaletteData(rgbs)); - } - } - if (blackIndex == -1) { - /* There was no black in the palette, so just copy the data over */ - System.arraycopy(source.data, 0, imageData.data, 0, imageData.data.length); - } else { - /* Modify the source image to contain black wherever the mask is 0 */ - int[] imagePixels = new int[imageData.width]; - int[] maskPixels = new int[mask.width]; - for (int y = 0; y < imageData.height; y++) { - source.getPixels(0, y, imageData.width, imagePixels, 0); - mask.getPixels(0, y, mask.width, maskPixels, 0); - for (int i = 0; i < imagePixels.length; i++) { - if (maskPixels[i] == 0) imagePixels[i] = blackIndex; - } - imageData.setPixels(0, y, source.width, imagePixels, 0); - } - } - imageData.maskPad = mask.scanlinePad; - imageData.maskData = mask.data; - return init(device, image, imageData); -} -void init(ImageData i) { - if (i == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - init(device, this, i); -} - -/** - * 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 /*long*/ internal_new_GC (GCData data) { - if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - /* - * Create a new GC that can draw into the image. - * Only supported for bitmaps. - */ - if (type != SWT.BITMAP || memGC != null) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - - /* Create a compatible HDC for the device */ - int /*long*/ hDC = device.internal_new_GC(null); - int /*long*/ imageDC = OS.CreateCompatibleDC(hDC); - device.internal_dispose_GC(hDC, null); - if (imageDC == 0) SWT.error(SWT.ERROR_NO_HANDLES); - - if (data != null) { - /* Set the GCData fields */ - int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT; - if ((data.style & mask) != 0) { - data.layout = (data.style & SWT.RIGHT_TO_LEFT) != 0 ? OS.LAYOUT_RTL : 0; - } else { - data.style |= SWT.LEFT_TO_RIGHT; - } - data.device = device; - data.image = this; - data.font = device.systemFont; - } - return imageDC; -} - -/** - * 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 /*long*/ hDC, GCData data) { - OS.DeleteDC(hDC); -} - -/** - * 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) { - /* - * Note. Not implemented on WinCE. - */ - if (OS.IsWinCE) return; - 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; - transparentColor = -1; - - /* Get the HDC for the device */ - int /*long*/ hDC = device.internal_new_GC(null); - - /* Change the background color in the image */ - BITMAP bm = new BITMAP(); - OS.GetObject(handle, BITMAP.sizeof, bm); - int /*long*/ hdcMem = OS.CreateCompatibleDC(hDC); - OS.SelectObject(hdcMem, handle); - int maxColors = 1 << bm.bmBitsPixel; - byte[] colors = new byte[maxColors * 4]; - if (OS.IsWinCE) SWT.error(SWT.ERROR_NOT_IMPLEMENTED); - int numColors = OS.GetDIBColorTable(hdcMem, 0, maxColors, colors); - int offset = transparentPixel * 4; - colors[offset] = (byte)color.getBlue(); - colors[offset + 1] = (byte)color.getGreen(); - colors[offset + 2] = (byte)color.getRed(); - if (OS.IsWinCE) SWT.error(SWT.ERROR_NOT_IMPLEMENTED); - OS.SetDIBColorTable(hdcMem, 0, numColors, colors); - OS.DeleteDC(hdcMem); - - /* Release the HDC for the device */ - device.internal_dispose_GC(hDC, 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 "Image {*DISPOSED*}"; - return "Image {" + handle + "}"; -} - -/** - * 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 - * @return a new image object containing the specified device, type and handle - */ -public static Image win32_new(Device device, int type, int /*long*/ handle) { - Image image = new Image(device); - image.type = type; - image.handle = handle; - return image; -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Path.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Path.java deleted file mode 100644 index db666da42b..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Path.java +++ /dev/null @@ -1,602 +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.gdip.*; -import org.eclipse.swt.internal.win32.*; - -/** - * 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 /*long*/ handle; - - PointF currentPoint = new PointF(), startPoint = new PointF(); - -/** - * 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); - this.device.checkGDIP(); - handle = Gdip.GraphicsPath_new(Gdip.FillModeAlternate); - 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); - handle = Gdip.GraphicsPath_Clone(path.handle); - if (flatness != 0) Gdip.GraphicsPath_Flatten(handle, 0, flatness); - if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); - 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); - if (width < 0) { - x = x + width; - width = -width; - } - if (height < 0) { - y = y + height; - height = -height; - } - if (width == 0 || height == 0 || arcAngle == 0) return; - if (width == height) { - Gdip.GraphicsPath_AddArc(handle, x, y, width, height, -startAngle, -arcAngle); - } else { - int /*long*/ path = Gdip.GraphicsPath_new(Gdip.FillModeAlternate); - if (path == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int /*long*/ matrix = Gdip.Matrix_new(width, 0, 0, height, x, y); - if (matrix == 0) SWT.error(SWT.ERROR_NO_HANDLES); - Gdip.GraphicsPath_AddArc(path, 0, 0, 1, 1, -startAngle, -arcAngle); - Gdip.GraphicsPath_Transform(path, matrix); - Gdip.GraphicsPath_AddPath(handle, path, true); - Gdip.Matrix_delete(matrix); - Gdip.GraphicsPath_delete(path); - } - Gdip.GraphicsPath_GetLastPoint(handle, currentPoint); -} - -/** - * 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); - //TODO - expose connect? - Gdip.GraphicsPath_AddPath(handle, path.handle, false); - currentPoint.X = path.currentPoint.X; - currentPoint.Y = path.currentPoint.Y; -} - -/** - * 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); - RectF rect = new RectF(); - rect.X = x; - rect.Y = y; - rect.Width = width; - rect.Height = height; - Gdip.GraphicsPath_AddRectangle(handle, rect); - currentPoint.X = x; - currentPoint.Y = y; -} - -/** - * 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(); - char[] buffer = new char[length]; - string.getChars(0, length, buffer, 0); - int /*long*/ hDC = device.internal_new_GC(null); - int /*long*/ [] family = new int /*long*/ [1]; - int /*long*/ gdipFont = GC.createGdipFont(hDC, font.handle, 0, device.fontCollection, family, null); - PointF point = new PointF(); - point.X = x - (Gdip.Font_GetSize(gdipFont) / 6); - point.Y = y; - int style = Gdip.Font_GetStyle(gdipFont); - float size = Gdip.Font_GetSize(gdipFont); - Gdip.GraphicsPath_AddString(handle, buffer, length, family[0], style, size, point, 0); - Gdip.GraphicsPath_GetLastPoint(handle, currentPoint); - Gdip.FontFamily_delete(family[0]); - Gdip.Font_delete(gdipFont); - device.internal_dispose_GC(hDC, null); -} - -/** - * 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); - Gdip.GraphicsPath_CloseFigure(handle); - /* - * Feature in GDI+. CloseFigure() does affect the last - * point, so GetLastPoint() does not return the starting - * point of the subpath after calling CloseFigure(). The - * fix is to remember the subpath starting point and use - * it instead. - */ - currentPoint.X = startPoint.X; - currentPoint.Y = startPoint.Y; -} - -/** - * 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); - //TODO - should use GC transformation - gc.initGdip(); - gc.checkGC(GC.LINE_CAP | GC.LINE_JOIN | GC.LINE_STYLE | GC.LINE_WIDTH); - int mode = OS.GetPolyFillMode(gc.handle) == OS.WINDING ? Gdip.FillModeWinding : Gdip.FillModeAlternate; - Gdip.GraphicsPath_SetFillMode(handle, mode); - if (outline) { - return Gdip.GraphicsPath_IsOutlineVisible(handle, x, y, gc.data.gdipPen, gc.data.gdipGraphics); - } else { - return Gdip.GraphicsPath_IsVisible(handle, x, y, gc.data.gdipGraphics); - } -} - -/** - * 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); - Gdip.GraphicsPath_AddBezier(handle, currentPoint.X, currentPoint.Y, cx1, cy1, cx2, cy2, x, y); - Gdip.GraphicsPath_GetLastPoint(handle, currentPoint); -} - -void destroy() { - Gdip.GraphicsPath_delete(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); - RectF rect = new RectF(); - Gdip.GraphicsPath_GetBounds(handle, rect, 0, 0); - 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); - point[0] = currentPoint.X; - point[1] = currentPoint.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); - int count = Gdip.GraphicsPath_GetPointCount(handle); - byte[] gdipTypes = new byte[count]; - float[] points = new float[count * 2]; - Gdip.GraphicsPath_GetPathTypes(handle, gdipTypes, count); - Gdip.GraphicsPath_GetPathPoints(handle, points, count); - byte[] types = new byte[count * 2]; - int index = 0, typesIndex = 0; - while (index < count) { - byte type = gdipTypes[index]; - boolean close = false; - switch (type & Gdip.PathPointTypePathTypeMask) { - case Gdip.PathPointTypeStart: - types[typesIndex++] = SWT.PATH_MOVE_TO; - close = (type & Gdip.PathPointTypeCloseSubpath) != 0; - index += 1; - break; - case Gdip.PathPointTypeLine: - types[typesIndex++] = SWT.PATH_LINE_TO; - close = (type & Gdip.PathPointTypeCloseSubpath) != 0; - index += 1; - break; - case Gdip.PathPointTypeBezier: - types[typesIndex++] = SWT.PATH_CUBIC_TO; - close = (gdipTypes[index + 2] & Gdip.PathPointTypeCloseSubpath) != 0; - index += 3; - break; - default: - index++; - } - if (close) { - types[typesIndex++] = SWT.PATH_CLOSE; - } - } - if (typesIndex != types.length) { - byte[] newTypes = new byte[typesIndex]; - System.arraycopy(types, 0, newTypes, 0, typesIndex); - types = newTypes; - } - PathData result = new PathData(); - result.types = types; - result.points = points; - return result; -} - -/** - * 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); - Gdip.GraphicsPath_AddLine(handle, currentPoint.X, currentPoint.Y, x, y); - Gdip.GraphicsPath_GetLastPoint(handle, currentPoint); -} - -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; -} - -/** - * 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); - Gdip.GraphicsPath_StartFigure(handle); - currentPoint.X = startPoint.X = x; - currentPoint.Y = startPoint.Y = y; -} - -/** - * 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); - float cx1 = currentPoint.X + 2 * (cx - currentPoint.X) / 3; - float cy1 = currentPoint.Y + 2 * (cy - currentPoint.Y) / 3; - float cx2 = cx1 + (x - currentPoint.X) / 3; - float cy2 = cy1 + (y - currentPoint.Y) / 3; - Gdip.GraphicsPath_AddBezier(handle, currentPoint.X, currentPoint.Y, cx1, cy1, cx2, cy2, x, y); - Gdip.GraphicsPath_GetLastPoint(handle, currentPoint); -} - -/** - * 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/win32/org/eclipse/swt/graphics/Pattern.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Pattern.java deleted file mode 100644 index 406fcec965..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Pattern.java +++ /dev/null @@ -1,250 +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.gdip.*; -import org.eclipse.swt.internal.win32.*; - -/** - * 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 { - - /** - * the OS resource for the Pattern - * (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 /*long*/ handle; - -/** - * 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); - this.device.checkGDIP(); - int /*long*/[] gdipImage = image.createGdipImage(); - int /*long*/ img = gdipImage[0]; - int width = Gdip.Image_GetWidth(img); - int height = Gdip.Image_GetHeight(img); - handle = Gdip.TextureBrush_new(img, Gdip.WrapModeTile, 0, 0, width, height); - Gdip.Bitmap_delete(img); - if (gdipImage[1] != 0) { - int /*long*/ hHeap = OS.GetProcessHeap (); - OS.HeapFree(hHeap, 0, gdipImage[1]); - } - if (handle == 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); - this.device.checkGDIP(); - int colorRef1 = color1.handle; - int rgb = ((colorRef1 >> 16) & 0xFF) | (colorRef1 & 0xFF00) | ((colorRef1 & 0xFF) << 16); - int /*long*/ foreColor = Gdip.Color_new((alpha1 & 0xFF) << 24 | rgb); - if (x1 == x2 && y1 == y2) { - handle = Gdip.SolidBrush_new(foreColor); - if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); - } else { - int colorRef2 = color2.handle; - rgb = ((colorRef2 >> 16) & 0xFF) | (colorRef2 & 0xFF00) | ((colorRef2 & 0xFF) << 16); - int /*long*/ backColor = Gdip.Color_new((alpha2 & 0xFF) << 24 | rgb); - PointF p1 = new PointF(); - p1.X = x1; - p1.Y = y1; - PointF p2 = new PointF(); - p2.X = x2; - p2.Y = y2; - handle = Gdip.LinearGradientBrush_new(p1, p2, foreColor, backColor); - if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); - if (alpha1 != 0xFF || alpha2 != 0xFF) { - int a = (int)((alpha1 & 0xFF) * 0.5f + (alpha2 & 0xFF) * 0.5f); - int r = (int)(((colorRef1 & 0xFF) >> 0) * 0.5f + ((colorRef2 & 0xFF) >> 0) * 0.5f); - int g = (int)(((colorRef1 & 0xFF00) >> 8) * 0.5f + ((colorRef2 & 0xFF00) >> 8) * 0.5f); - int b = (int)(((colorRef1 & 0xFF0000) >> 16) * 0.5f + ((colorRef2 & 0xFF0000) >> 16) * 0.5f); - int /*long*/ midColor = Gdip.Color_new(a << 24 | r << 16 | g << 8 | b); - Gdip.LinearGradientBrush_SetInterpolationColors(handle, new int /*long*/ []{foreColor, midColor, backColor}, new float[]{0, 0.5f, 1}, 3); - Gdip.Color_delete(midColor); - } - Gdip.Color_delete(backColor); - } - Gdip.Color_delete(foreColor); - init(); -} - -void destroy() { - int type = Gdip.Brush_GetType(handle); - switch (type) { - case Gdip.BrushTypeSolidColor: - Gdip.SolidBrush_delete(handle); - break; - case Gdip.BrushTypeHatchFill: - Gdip.HatchBrush_delete(handle); - break; - case Gdip.BrushTypeLinearGradient: - Gdip.LinearGradientBrush_delete(handle); - break; - case Gdip.BrushTypeTextureFill: - Gdip.TextureBrush_delete(handle); - break; - } - handle = 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 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 "Pattern {*DISPOSED*}"; - return "Pattern {" + handle + "}"; -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Region.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Region.java deleted file mode 100755 index 5c6383328a..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/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.win32.*; -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 /*long*/ 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.CreateRectRgn (0, 0, 0, 0); - if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); - init(); -} - -/** - * Constructs a new region given a handle to the operating - * system resources that it should represent. - * - * @param handle the handle for the result - */ -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 (OS.IsWinCE) SWT.error(SWT.ERROR_NOT_IMPLEMENTED); - int /*long*/ polyRgn = OS.CreatePolygonRgn(pointArray, pointArray.length / 2, OS.ALTERNATE); - OS.CombineRgn (handle, handle, polyRgn, OS.RGN_OR); - OS.DeleteObject (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); - 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 /*long*/ rectRgn = OS.CreateRectRgn (x, y, x + width, y + height); - OS.CombineRgn (handle, handle, rectRgn, OS.RGN_OR); - OS.DeleteObject (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.CombineRgn (handle, handle, region.handle, OS.RGN_OR); -} - -/** - * 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); - return OS.PtInRegion (handle, x, y); -} - -/** - * 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 (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - if (pt == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - return contains(pt.x, pt.y); -} - -void destroy () { - OS.DeleteObject(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 rgn = (Region)object; - return handle == rgn.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 rect = new RECT(); - OS.GetRgnBox(handle, rect); - return new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); -} - -/** - * 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 (int)/*64*/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 /*long*/ rectRgn = OS.CreateRectRgn (x, y, x + width, y + height); - OS.CombineRgn (handle, handle, rectRgn, OS.RGN_AND); - OS.DeleteObject (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.CombineRgn (handle, handle, region.handle, OS.RGN_AND); -} - -/** - * 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 r = new RECT (); - OS.SetRect (r, x, y, x + width, y + height); - return OS.RectInRegion (handle, r); -} - -/** - * 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 (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - 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); - RECT rect = new RECT (); - int result = OS.GetRgnBox (handle, rect); - if (result == OS.NULLREGION) return true; - return ((rect.right - rect.left) <= 0) || ((rect.bottom - rect.top) <= 0); -} - -/** - * 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 (OS.IsWinCE) SWT.error(SWT.ERROR_NOT_IMPLEMENTED); - int /*long*/ polyRgn = OS.CreatePolygonRgn(pointArray, pointArray.length / 2, OS.ALTERNATE); - OS.CombineRgn (handle, handle, polyRgn, OS.RGN_DIFF); - OS.DeleteObject (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 /*long*/ rectRgn = OS.CreateRectRgn (x, y, x + width, y + height); - OS.CombineRgn (handle, handle, rectRgn, OS.RGN_DIFF); - OS.DeleteObject (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.CombineRgn (handle, handle, region.handle, OS.RGN_DIFF); -} - -/** - * 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, x, 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 + "}"; -} - -/** - * Invokes platform specific functionality to allocate a new region. - * <p> - * <b>IMPORTANT:</b> This method is <em>not</em> part of the public - * API for <code>Region</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 region - * @param handle the handle for the region - * @return a new region object containing the specified device and handle - */ -public static Region win32_new(Device device, int handle) { - return new Region(device, handle); -} - -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java deleted file mode 100644 index d4701a120f..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java +++ /dev/null @@ -1,3328 +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.gdip.*; -import org.eclipse.swt.internal.win32.*; -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 { - Font font; - String text, segmentsText; - int lineSpacing; - int ascent, descent; - int alignment; - int wrapWidth; - int orientation; - int indent; - boolean justify; - int[] tabs; - int[] segments; - StyleItem[] styles; - int stylesCount; - - StyleItem[] allRuns; - StyleItem[][] runs; - int[] lineOffset, lineY, lineWidth; - int /*long*/ mLangFontLink2; - - static final char LTR_MARK = '\u200E', RTL_MARK = '\u200F'; - static final int SCRIPT_VISATTR_SIZEOF = 2; - static final int GOFFSET_SIZEOF = 8; - static final byte[] CLSID_CMultiLanguage = new byte[16]; - static final byte[] IID_IMLangFontLink2 = new byte[16]; - static { - OS.IIDFromString("{275c23e2-3747-11d0-9fea-00aa003f8646}\0".toCharArray(), CLSID_CMultiLanguage); - OS.IIDFromString("{DCCFC162-2B38-11d2-B7EC-00C04F8F5D9A}\0".toCharArray(), IID_IMLangFontLink2); - } - - static final int MERGE_MAX = 512; - static final int TOO_MANY_RUNS = 1024; - - /* IME has a copy of these constants */ - static final int UNDERLINE_IME_DOT = 1 << 16; - static final int UNDERLINE_IME_DASH = 2 << 16; - static final int UNDERLINE_IME_THICK = 3 << 16; - - class StyleItem { - TextStyle style; - int start, length; - boolean lineBreak, softBreak, tab; - - /*Script cache and analysis */ - SCRIPT_ANALYSIS analysis; - int /*long*/ psc = 0; - - /*Shape info (malloc when the run is shaped) */ - int /*long*/ glyphs; - int glyphCount; - int /*long*/ clusters; - int /*long*/ visAttrs; - - /*Place info (malloc when the run is placed) */ - int /*long*/ advances; - int /*long*/ goffsets; - int width; - int ascent; - int descent; - int leading; - int x; - int underlinePos, underlineThickness; - int strikeoutPos, strikeoutThickness; - - /* Justify info (malloc during computeRuns) */ - int /*long*/ justify; - - /* ScriptBreak */ - int /*long*/ psla; - - int /*long*/ fallbackFont; - - void free() { - int /*long*/ hHeap = OS.GetProcessHeap(); - if (psc != 0) { - OS.ScriptFreeCache (psc); - OS.HeapFree(hHeap, 0, psc); - psc = 0; - } - if (glyphs != 0) { - OS.HeapFree(hHeap, 0, glyphs); - glyphs = 0; - glyphCount = 0; - } - if (clusters != 0) { - OS.HeapFree(hHeap, 0, clusters); - clusters = 0; - } - if (visAttrs != 0) { - OS.HeapFree(hHeap, 0, visAttrs); - visAttrs = 0; - } - if (advances != 0) { - OS.HeapFree(hHeap, 0, advances); - advances = 0; - } - if (goffsets != 0) { - OS.HeapFree(hHeap, 0, goffsets); - goffsets = 0; - } - if (justify != 0) { - OS.HeapFree(hHeap, 0, justify); - justify = 0; - } - if (psla != 0) { - OS.HeapFree(hHeap, 0, psla); - psla = 0; - } - if (fallbackFont != 0) { - OS.DeleteObject(fallbackFont); - fallbackFont = 0; - } - width = ascent = descent = x = 0; - lineBreak = softBreak = false; - } - public String toString () { - return "StyleItem {" + start + ", " + style + "}"; - } - } - -/** - * 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); - wrapWidth = ascent = descent = -1; - lineSpacing = 0; - orientation = SWT.LEFT_TO_RIGHT; - styles = new StyleItem[2]; - styles[0] = new StyleItem(); - styles[1] = new StyleItem(); - stylesCount = 2; - text = ""; //$NON-NLS-1$ - int /*long*/[] ppv = new int /*long*/[1]; - OS.OleInitialize(0); - if (OS.CoCreateInstance(CLSID_CMultiLanguage, 0, OS.CLSCTX_INPROC_SERVER, IID_IMLangFontLink2, ppv) == OS.S_OK) { - mLangFontLink2 = ppv[0]; - } - init(); -} - -RECT addClipRect(StyleItem run, RECT clipRect, RECT rect, int selectionStart, int selectionEnd) { - if (rect != null) { - if (clipRect == null) { - clipRect = new RECT (); - OS.SetRect(clipRect, -1, rect.top, -1, rect.bottom); - } - boolean isRTL = (orientation & SWT.RIGHT_TO_LEFT) != 0; - if (run.start <= selectionStart && selectionStart <= run.start + run.length) { - if (run.analysis.fRTL ^ isRTL) { - clipRect.right = rect.left; - } else { - clipRect.left = rect.left; - } - } - if (run.start <= selectionEnd && selectionEnd <= run.start + run.length) { - if (run.analysis.fRTL ^ isRTL) { - clipRect.left = rect.right; - } else { - clipRect.right = rect.right; - } - } - } - return clipRect; -} - -void breakRun(StyleItem run) { - if (run.psla != 0) return; - char[] chars = new char[run.length]; - segmentsText.getChars(run.start, run.start + run.length, chars, 0); - int /*long*/ hHeap = OS.GetProcessHeap(); - run.psla = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, SCRIPT_LOGATTR.sizeof * chars.length); - if (run.psla == 0) SWT.error(SWT.ERROR_NO_HANDLES); - OS.ScriptBreak(chars, chars.length, run.analysis, run.psla); -} - -void checkLayout () { - if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); -} - -/* -* Compute the runs: itemize, shape, place, and reorder the runs. -* Break paragraphs into lines, wraps the text, and initialize caches. -*/ -void computeRuns (GC gc) { - if (runs != null) return; - int /*long*/ hDC = gc != null ? gc.handle : device.internal_new_GC(null); - int /*long*/ srcHdc = OS.CreateCompatibleDC(hDC); - allRuns = itemize(); - for (int i=0; i<allRuns.length - 1; i++) { - StyleItem run = allRuns[i]; - OS.SelectObject(srcHdc, getItemFont(run)); - shape(srcHdc, run); - } - SCRIPT_LOGATTR logAttr = new SCRIPT_LOGATTR(); - SCRIPT_PROPERTIES properties = new SCRIPT_PROPERTIES(); - int lineWidth = indent, lineStart = 0, lineCount = 1; - for (int i=0; i<allRuns.length - 1; i++) { - StyleItem run = allRuns[i]; - if (tabs != null && run.tab) { - int tabsLength = tabs.length, j; - for (j = 0; j < tabsLength; j++) { - if (tabs[j] > lineWidth) { - run.width = tabs[j] - lineWidth; - break; - } - } - if (j == tabsLength) { - int tabX = tabs[tabsLength-1]; - int lastTabWidth = tabsLength > 1 ? tabs[tabsLength-1] - tabs[tabsLength-2] : tabs[0]; - if (lastTabWidth > 0) { - while (tabX <= lineWidth) tabX += lastTabWidth; - run.width = tabX - lineWidth; - } - } - int length = run.length; - if (length > 1) { - int stop = j + length - 1; - if (stop < tabsLength) { - run.width += tabs[stop] - tabs[j]; - } else { - if (j < tabsLength) { - run.width += tabs[tabsLength - 1] - tabs[j]; - length -= (tabsLength - 1) - j; - } - int lastTabWidth = tabsLength > 1 ? tabs[tabsLength-1] - tabs[tabsLength-2] : tabs[0]; - run.width += lastTabWidth * (length - 1); - } - } - } - if (wrapWidth != -1 && lineWidth + run.width > wrapWidth && !run.tab) { - int start = 0; - int[] piDx = new int[run.length]; - if (run.style != null && run.style.metrics != null) { - piDx[0] = run.width; - } else { - OS.ScriptGetLogicalWidths(run.analysis, run.length, run.glyphCount, run.advances, run.clusters, run.visAttrs, piDx); - } - int width = 0, maxWidth = wrapWidth - lineWidth; - while (width + piDx[start] < maxWidth) { - width += piDx[start++]; - } - int firstStart = start; - int firstIndice = i; - while (i >= lineStart) { - breakRun(run); - while (start >= 0) { - OS.MoveMemory(logAttr, run.psla + (start * SCRIPT_LOGATTR.sizeof), SCRIPT_LOGATTR.sizeof); - if (logAttr.fSoftBreak || logAttr.fWhiteSpace) break; - start--; - } - - /* - * Bug in Windows. For some reason Uniscribe sets the fSoftBreak flag for the first letter - * after a letter with an accent. This cause a break line to be set in the middle of a word. - * The fix is to detect the case and ignore fSoftBreak forcing the algorithm keep searching. - */ - if (start == 0 && i != lineStart && !run.tab) { - if (logAttr.fSoftBreak && !logAttr.fWhiteSpace) { - OS.MoveMemory(properties, device.scripts[run.analysis.eScript], SCRIPT_PROPERTIES.sizeof); - int langID = properties.langid; - StyleItem pRun = allRuns[i - 1]; - OS.MoveMemory(properties, device.scripts[pRun.analysis.eScript], SCRIPT_PROPERTIES.sizeof); - if (properties.langid == langID || langID == OS.LANG_NEUTRAL || properties.langid == OS.LANG_NEUTRAL) { - breakRun(pRun); - OS.MoveMemory(logAttr, pRun.psla + ((pRun.length - 1) * SCRIPT_LOGATTR.sizeof), SCRIPT_LOGATTR.sizeof); - if (!logAttr.fWhiteSpace) start = -1; - } - } - } - if (start >= 0 || i == lineStart) break; - run = allRuns[--i]; - start = run.length - 1; - } - if (start == 0 && i != lineStart && !run.tab) { - run = allRuns[--i]; - } else if (start <= 0 && i == lineStart) { - if (lineWidth == wrapWidth && firstIndice > 0) { - i = firstIndice - 1; - run = allRuns[i]; - start = run.length; - } else { - i = firstIndice; - run = allRuns[i]; - start = Math.max(1, firstStart); - } - } - breakRun(run); - while (start < run.length) { - OS.MoveMemory(logAttr, run.psla + (start * SCRIPT_LOGATTR.sizeof), SCRIPT_LOGATTR.sizeof); - if (!logAttr.fWhiteSpace) break; - start++; - } - if (0 < start && start < run.length) { - StyleItem newRun = new StyleItem(); - newRun.start = run.start + start; - newRun.length = run.length - start; - newRun.style = run.style; - newRun.analysis = cloneScriptAnalysis(run.analysis); - run.free(); - run.length = start; - OS.SelectObject(srcHdc, getItemFont(run)); - run.analysis.fNoGlyphIndex = false; - shape (srcHdc, run); - OS.SelectObject(srcHdc, getItemFont(newRun)); - newRun.analysis.fNoGlyphIndex = false; - shape (srcHdc, newRun); - StyleItem[] newAllRuns = new StyleItem[allRuns.length + 1]; - System.arraycopy(allRuns, 0, newAllRuns, 0, i + 1); - System.arraycopy(allRuns, i + 1, newAllRuns, i + 2, allRuns.length - i - 1); - allRuns = newAllRuns; - allRuns[i + 1] = newRun; - } - if (i != allRuns.length - 2) { - run.softBreak = run.lineBreak = true; - } - } - lineWidth += run.width; - if (run.lineBreak) { - lineStart = i + 1; - lineWidth = run.softBreak ? 0 : indent; - lineCount++; - } - } - lineWidth = 0; - runs = new StyleItem[lineCount][]; - lineOffset = new int[lineCount + 1]; - lineY = new int[lineCount + 1]; - this.lineWidth = new int[lineCount]; - int lineRunCount = 0, line = 0; - int ascent = Math.max(0, this.ascent); - int descent = Math.max(0, this.descent); - StyleItem[] lineRuns = new StyleItem[allRuns.length]; - for (int i=0; i<allRuns.length; i++) { - StyleItem run = allRuns[i]; - lineRuns[lineRunCount++] = run; - lineWidth += run.width; - ascent = Math.max(ascent, run.ascent); - descent = Math.max(descent, run.descent); - if (run.lineBreak || i == allRuns.length - 1) { - /* Update the run metrics if the last run is a hard break. */ - if (lineRunCount == 1 && (i == allRuns.length - 1 || !run.softBreak)) { - TEXTMETRIC lptm = OS.IsUnicode ? (TEXTMETRIC)new TEXTMETRICW() : new TEXTMETRICA(); - OS.SelectObject(srcHdc, getItemFont(run)); - OS.GetTextMetrics(srcHdc, lptm); - run.ascent = lptm.tmAscent; - run.descent = lptm.tmDescent; - ascent = Math.max(ascent, run.ascent); - descent = Math.max(descent, run.descent); - } - runs[line] = new StyleItem[lineRunCount]; - System.arraycopy(lineRuns, 0, runs[line], 0, lineRunCount); - - if (justify && wrapWidth != -1 && run.softBreak && lineWidth > 0) { - if (line == 0) { - lineWidth += indent; - } else { - StyleItem[] previousLine = runs[line - 1]; - StyleItem previousRun = previousLine[previousLine.length - 1]; - if (previousRun.lineBreak && !previousRun.softBreak) { - lineWidth += indent; - } - } - int /*long*/ hHeap = OS.GetProcessHeap(); - int newLineWidth = 0; - for (int j = 0; j < runs[line].length; j++) { - StyleItem item = runs[line][j]; - int iDx = item.width * wrapWidth / lineWidth; - if (iDx != item.width) { - item.justify = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, item.glyphCount * 4); - if (item.justify == 0) SWT.error(SWT.ERROR_NO_HANDLES); - OS.ScriptJustify(item.visAttrs, item.advances, item.glyphCount, iDx - item.width, 2, item.justify); - item.width = iDx; - } - newLineWidth += item.width; - } - lineWidth = newLineWidth; - } - this.lineWidth[line] = lineWidth; - - StyleItem lastRun = runs[line][lineRunCount - 1]; - int lastOffset = lastRun.start + lastRun.length; - runs[line] = reorder(runs[line], i == allRuns.length - 1); - lastRun = runs[line][lineRunCount - 1]; - if (run.softBreak && run != lastRun) { - run.softBreak = run.lineBreak = false; - lastRun.softBreak = lastRun.lineBreak = true; - } - - lineWidth = getLineIndent(line); - for (int j = 0; j < runs[line].length; j++) { - runs[line][j].x = lineWidth; - lineWidth += runs[line][j].width; - } - line++; - lineY[line] = lineY[line - 1] + ascent + descent + lineSpacing; - lineOffset[line] = lastOffset; - lineRunCount = lineWidth = 0; - ascent = Math.max(0, this.ascent); - descent = Math.max(0, this.descent); - } - } - if (srcHdc != 0) OS.DeleteDC(srcHdc); - if (gc == null) device.internal_dispose_GC(hDC, null); -} - -void destroy () { - freeRuns(); - font = null; - text = null; - segmentsText = null; - tabs = null; - styles = null; - runs = null; - lineOffset = null; - lineY = null; - lineWidth = null; - if (mLangFontLink2 != 0) { - /* Release() */ - OS.VtblCall(2, mLangFontLink2); - mLangFontLink2 = 0; - } - OS.OleUninitialize(); -} - -SCRIPT_ANALYSIS cloneScriptAnalysis (SCRIPT_ANALYSIS src) { - SCRIPT_ANALYSIS dst = new SCRIPT_ANALYSIS(); - dst.eScript = src.eScript; - dst.fRTL = src.fRTL; - dst.fLayoutRTL = src.fLayoutRTL; - dst.fLinkBefore = src.fLinkBefore; - dst.fLinkAfter = src.fLinkAfter; - dst.fLogicalOrder = src.fLogicalOrder; - dst.fNoGlyphIndex = src.fNoGlyphIndex; - dst.s = new SCRIPT_STATE(); - dst.s.uBidiLevel = src.s.uBidiLevel; - dst.s.fOverrideDirection = src.s.fOverrideDirection; - dst.s.fInhibitSymSwap = src.s.fInhibitSymSwap; - dst.s.fCharShape = src.s.fCharShape; - dst.s.fDigitSubstitute = src.s.fDigitSubstitute; - dst.s.fInhibitLigate = src.s.fInhibitLigate; - dst.s.fDisplayZWG = src.s.fDisplayZWG; - dst.s.fArabicNumContext = src.s.fArabicNumContext; - dst.s.fGcpClusters = src.s.fGcpClusters; - dst.s.fReserved = src.s.fReserved; - dst.s.fEngineReserved = src.s.fEngineReserved; - return dst; -} - -int[] 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 int[0]; - - int[] coordinates = new int[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; -} - -int /*long*/ createGdipBrush(int pixel, int alpha) { - int argb = ((alpha & 0xFF) << 24) | ((pixel >> 16) & 0xFF) | (pixel & 0xFF00) | ((pixel & 0xFF) << 16); - int /*long*/ gdiColor = Gdip.Color_new(argb); - int /*long*/ brush = Gdip.SolidBrush_new(gdiColor); - Gdip.Color_delete(gdiColor); - return brush; -} - -int /*long*/ createGdipBrush(Color color, int alpha) { - return createGdipBrush(color.handle, alpha); -} - -/** - * 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(gc); - 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 = text.length(); - if (length == 0 && flags == 0) return; - int /*long*/ hdc = gc.handle; - Rectangle clip = gc.getClipping(); - GCData data = gc.data; - int /*long*/ gdipGraphics = data.gdipGraphics; - int foreground = data.foreground; - int linkColor = OS.GetSysColor (OS.COLOR_HOTLIGHT); - int alpha = data.alpha; - boolean gdip = gdipGraphics != 0; - int /*long*/ gdipForeground = 0; - int /*long*/ gdipLinkColor = 0; - int state = 0; - if (gdip) { - gc.checkGC(GC.FOREGROUND); - gdipForeground = gc.getFgBrush(); - } else { - state = OS.SaveDC(hdc); - if ((data.style & SWT.MIRRORED) != 0) { - OS.SetLayout(hdc, OS.GetLayout(hdc) | OS.LAYOUT_RTL); - } - } - boolean hasSelection = selectionStart <= selectionEnd && selectionStart != -1 && selectionEnd != -1; - int /*long*/ gdipSelBackground = 0, gdipSelForeground = 0, gdipFont = 0, lastHFont = 0; - int /*long*/ selBackground = 0; - int selForeground = 0; - if (hasSelection || (flags & SWT.LAST_LINE_SELECTION) != 0) { - int fgSel = selectionForeground != null ? selectionForeground.handle : OS.GetSysColor (OS.COLOR_HIGHLIGHTTEXT); - int bgSel = selectionBackground != null ? selectionBackground.handle : OS.GetSysColor (OS.COLOR_HIGHLIGHT); - if (gdip) { - gdipSelBackground = createGdipBrush(bgSel, alpha); - gdipSelForeground = createGdipBrush(fgSel, alpha); - } else { - selBackground = OS.CreateSolidBrush(bgSel); - selForeground = fgSel; - } - if (hasSelection) { - selectionStart = translateOffset(Math.min(Math.max(0, selectionStart), length - 1)); - selectionEnd = translateOffset(Math.min(Math.max(0, selectionEnd), length - 1)); - } - } - RECT rect = new RECT(); - OS.SetBkMode(hdc, OS.TRANSPARENT); - for (int line=0; line<runs.length; line++) { - int drawX = x + getLineIndent(line); - int drawY = y + lineY[line]; - StyleItem[] lineRuns = runs[line]; - int lineHeight = lineY[line+1] - lineY[line] - lineSpacing; - - //Draw last line selection - if (flags != 0 && (hasSelection || (flags & SWT.LAST_LINE_SELECTION) != 0)) { - boolean extents = false; - if (line == runs.length - 1 && (flags & SWT.LAST_LINE_SELECTION) != 0) { - extents = true; - } else { - StyleItem run = lineRuns[lineRuns.length - 1]; - if (run.lineBreak && !run.softBreak) { - if (selectionStart <= run.start && run.start <= selectionEnd) extents = true; - } else { - int endOffset = run.start + run.length - 1; - if (selectionStart <= endOffset && endOffset < selectionEnd && (flags & SWT.FULL_SELECTION) != 0) { - extents = true; - } - } - } - if (extents) { - int width; - if ((flags & SWT.FULL_SELECTION) != 0) { - width = OS.IsWin95 ? 0x7FFF : 0x6FFFFFF; - } else { - width = lineHeight / 3; - } - if (gdip) { - Gdip.Graphics_FillRectangle(gdipGraphics, gdipSelBackground, drawX + lineWidth[line], drawY, width, lineHeight); - } else { - OS.SelectObject(hdc, selBackground); - OS.PatBlt(hdc, drawX + lineWidth[line], drawY, width, lineHeight, OS.PATCOPY); - } - } - } - if (drawX > clip.x + clip.width) continue; - if (drawX + lineWidth[line] < clip.x) continue; - - //Draw the background of the runs in the line - int alignmentX = drawX; - for (int i = 0; i < lineRuns.length; i++) { - StyleItem run = lineRuns[i]; - if (run.length == 0) continue; - if (drawX > clip.x + clip.width) break; - if (drawX + run.width >= clip.x) { - if (!run.lineBreak || run.softBreak) { - OS.SetRect(rect, drawX, drawY, drawX + run.width, drawY + lineHeight); - if (gdip) { - drawRunBackgroundGDIP(run, gdipGraphics, rect, selectionStart, selectionEnd, alpha, gdipSelBackground, hasSelection); - } else { - drawRunBackground(run, hdc, rect, selectionStart, selectionEnd, selBackground, hasSelection); - } - } - } - drawX += run.width; - } - - //Draw the text, underline, strikeout, and border of the runs in the line - int baseline = Math.max(0, this.ascent); - int lineUnderlinePos = 0; - for (int i = 0; i < lineRuns.length; i++) { - baseline = Math.max(baseline, lineRuns[i].ascent); - lineUnderlinePos = Math.min(lineUnderlinePos, lineRuns[i].underlinePos); - } - RECT borderClip = null, underlineClip = null, strikeoutClip = null, pRect = null; - drawX = alignmentX; - for (int i = 0; i < lineRuns.length; i++) { - StyleItem run = lineRuns[i]; - TextStyle style = run.style; - boolean hasAdorners = style != null && (style.underline || style.strikeout || style.borderStyle != SWT.NONE); - if (run.length == 0) continue; - if (drawX > clip.x + clip.width && !hasAdorners) break; - if (drawX + run.width >= clip.x || hasAdorners) { - boolean skipTab = run.tab && !hasAdorners; - if (!skipTab && (!run.lineBreak || run.softBreak) && !(style != null && style.metrics != null)) { - OS.SetRect(rect, drawX, drawY, drawX + run.width, drawY + lineHeight); - if (gdip) { - int /*long*/ hFont = getItemFont(run); - if (hFont != lastHFont) { - lastHFont = hFont; - if (gdipFont != 0) Gdip.Font_delete(gdipFont); - gdipFont = Gdip.Font_new(hdc, hFont); - if (gdipFont == 0) SWT.error(SWT.ERROR_NO_HANDLES); - if (!Gdip.Font_IsAvailable(gdipFont)) { - Gdip.Font_delete(gdipFont); - gdipFont = 0; - } - } - int /*long*/ gdipFg = gdipForeground; - if (style != null && style.underline && style.underlineStyle == SWT.UNDERLINE_LINK) { - if (gdipLinkColor == 0) gdipLinkColor = createGdipBrush(linkColor, alpha); - gdipFg = gdipLinkColor; - } - if (gdipFont != 0) { - pRect = drawRunTextGDIP(gdipGraphics, run, rect, gdipFont, baseline, gdipFg, gdipSelForeground, selectionStart, selectionEnd, alpha); - } else { - int fg = style != null && style.underline && style.underlineStyle == SWT.UNDERLINE_LINK ? linkColor : foreground; - pRect = drawRunTextGDIPRaster(gdipGraphics, run, rect, baseline, fg, selForeground, selectionStart, selectionEnd); - } - underlineClip = drawUnderlineGDIP(gdipGraphics, x, drawY + baseline, lineUnderlinePos, drawY + lineHeight, lineRuns, i, gdipFg, gdipSelForeground, underlineClip, pRect, selectionStart, selectionEnd, alpha); - strikeoutClip = drawStrikeoutGDIP(gdipGraphics, x, drawY + baseline, lineRuns, i, gdipFg, gdipSelForeground, strikeoutClip, pRect, selectionStart, selectionEnd, alpha); - borderClip = drawBorderGDIP(gdipGraphics, x, drawY, lineHeight, lineRuns, i, gdipFg, gdipSelForeground, borderClip, pRect, selectionStart, selectionEnd, alpha); - } else { - int fg = style != null && style.underline && style.underlineStyle == SWT.UNDERLINE_LINK ? linkColor : foreground; - pRect = drawRunText(hdc, run, rect, baseline, fg, selForeground, selectionStart, selectionEnd); - underlineClip = drawUnderline(hdc, x, drawY + baseline, lineUnderlinePos, drawY + lineHeight, lineRuns, i, fg, selForeground, underlineClip, pRect, selectionStart, selectionEnd); - strikeoutClip = drawStrikeout(hdc, x, drawY + baseline, lineRuns, i, fg, selForeground, strikeoutClip, pRect, selectionStart, selectionEnd); - borderClip = drawBorder(hdc, x, drawY, lineHeight, lineRuns, i, fg, selForeground, borderClip, pRect, selectionStart, selectionEnd); - } - } - } - drawX += run.width; - } - } - if (gdipSelBackground != 0) Gdip.SolidBrush_delete(gdipSelBackground); - if (gdipSelForeground != 0) Gdip.SolidBrush_delete(gdipSelForeground); - if (gdipLinkColor != 0) Gdip.SolidBrush_delete(gdipLinkColor); - if (gdipFont != 0) Gdip.Font_delete(gdipFont); - if (state != 0) OS.RestoreDC(hdc, state); - if (selBackground != 0) OS.DeleteObject (selBackground); -} - -RECT drawBorder(int /*long*/ hdc, int x, int y, int lineHeight, StyleItem[] line, int index, int color, int selectionColor, RECT clipRect, RECT pRect, int selectionStart, int selectionEnd) { - StyleItem run = line[index]; - TextStyle style = run.style; - if (style == null) return null; - if (style.borderStyle == SWT.NONE) return null; - clipRect = addClipRect(run, clipRect, pRect, selectionStart, selectionEnd); - if (index + 1 >= line.length || !style.isAdherentBorder(line[index + 1].style)) { - int left = run.x; - int start = run.start; - int end = run.start + run.length - 1; - for (int i = index; i > 0 && style.isAdherentBorder(line[i - 1].style); i--) { - left = line[i - 1].x; - start = Math.min(start, line[i - 1].start); - end = Math.max(end, line[i - 1].start + line[i - 1].length - 1); - } - boolean hasSelection = selectionStart <= selectionEnd && selectionStart != -1 && selectionEnd != -1; - boolean fullSelection = hasSelection && selectionStart <= start && end <= selectionEnd; - if (style.borderColor != null) { - color = style.borderColor.handle; - clipRect = null; - } else { - if (fullSelection) { - color = selectionColor; - clipRect = null; - } else { - if (style.foreground != null) { - color = style.foreground.handle; - } - } - } - int lineWidth = 1; - int lineStyle = OS.PS_SOLID; - switch (style.borderStyle) { - case SWT.BORDER_SOLID: break; - case SWT.BORDER_DASH: lineStyle = OS.PS_DASH; break; - case SWT.BORDER_DOT: lineStyle = OS.PS_DOT; break; - } - int /*long*/ oldBrush = OS.SelectObject(hdc, OS.GetStockObject(OS.NULL_BRUSH)); - LOGBRUSH logBrush = new LOGBRUSH(); - logBrush.lbStyle = OS.BS_SOLID; - logBrush.lbColor = /*64*/(int)color; - int /*long*/ newPen = OS.ExtCreatePen(lineStyle | OS.PS_GEOMETRIC, Math.max(1, lineWidth), logBrush, 0, null); - int /*long*/ oldPen = OS.SelectObject(hdc, newPen); - OS.Rectangle(hdc, x + left, y, x + run.x + run.width, y + lineHeight); - OS.SelectObject(hdc, oldPen); - OS.DeleteObject(newPen); - if (clipRect != null) { - int state = OS.SaveDC(hdc); - if (clipRect.left == -1) clipRect.left = 0; - if (clipRect.right == -1) clipRect.right = 0x7ffff; - OS.IntersectClipRect(hdc, clipRect.left, clipRect.top, clipRect.right, clipRect.bottom); - logBrush.lbColor = /*64*/(int)selectionColor; - int /*long*/ selPen = OS.ExtCreatePen (lineStyle | OS.PS_GEOMETRIC, Math.max(1, lineWidth), logBrush, 0, null); - oldPen = OS.SelectObject(hdc, selPen); - OS.Rectangle(hdc, x + left, y, x + run.x + run.width, y + lineHeight); - OS.RestoreDC(hdc, state); - OS.SelectObject(hdc, oldPen); - OS.DeleteObject(selPen); - } - OS.SelectObject(hdc, oldBrush); - return null; - } - return clipRect; -} - -RECT drawBorderGDIP(int /*long*/ graphics, int x, int y, int lineHeight, StyleItem[] line, int index, int /*long*/ color, int /*long*/ selectionColor, RECT clipRect, RECT pRect, int selectionStart, int selectionEnd, int alpha) { - StyleItem run = line[index]; - TextStyle style = run.style; - if (style == null) return null; - if (style.borderStyle == SWT.NONE) return null; - clipRect = addClipRect(run, clipRect, pRect, selectionStart, selectionEnd); - if (index + 1 >= line.length || !style.isAdherentBorder(line[index + 1].style)) { - int left = run.x; - int start = run.start; - int end = run.start + run.length - 1; - for (int i = index; i > 0 && style.isAdherentBorder(line[i - 1].style); i--) { - left = line[i - 1].x; - start = Math.min(start, line[i - 1].start); - end = Math.max(end, line[i - 1].start + line[i - 1].length - 1); - } - boolean hasSelection = selectionStart <= selectionEnd && selectionStart != -1 && selectionEnd != -1; - boolean fullSelection = hasSelection && selectionStart <= start && end <= selectionEnd; - int /*long*/ brush = color; - if (style.borderColor != null) { - brush = createGdipBrush(style.borderColor, alpha); - clipRect = null; - } else { - if (fullSelection) { - brush = selectionColor; - clipRect = null; - } else { - if (style.foreground != null) { - brush = createGdipBrush(style.foreground, alpha); - } - } - } - int lineWidth = 1; - int lineStyle = Gdip.DashStyleSolid; - switch (style.borderStyle) { - case SWT.BORDER_SOLID: break; - case SWT.BORDER_DASH: lineStyle = Gdip.DashStyleDash; break; - case SWT.BORDER_DOT: lineStyle = Gdip.DashStyleDot; break; - } - int /*long*/ pen = Gdip.Pen_new(brush, lineWidth); - Gdip.Pen_SetDashStyle(pen, lineStyle); - Gdip.Graphics_SetPixelOffsetMode(graphics, Gdip.PixelOffsetModeNone); - if (clipRect != null) { - int gstate = Gdip.Graphics_Save(graphics); - if (clipRect.left == -1) clipRect.left = 0; - if (clipRect.right == -1) clipRect.right = 0x7ffff; - Rect gdipRect = new Rect(); - gdipRect.X = clipRect.left; - gdipRect.Y = clipRect.top; - gdipRect.Width = clipRect.right - clipRect.left; - gdipRect.Height = clipRect.bottom - clipRect.top; - Gdip.Graphics_SetClip(graphics, gdipRect, Gdip.CombineModeExclude); - Gdip.Graphics_DrawRectangle(graphics, pen, x + left, y, run.x + run.width - left - 1, lineHeight - 1); - Gdip.Graphics_Restore(graphics, gstate); - gstate = Gdip.Graphics_Save(graphics); - Gdip.Graphics_SetClip(graphics, gdipRect, Gdip.CombineModeIntersect); - int /*long*/ selPen = Gdip.Pen_new(selectionColor, lineWidth); - Gdip.Pen_SetDashStyle(selPen, lineStyle); - Gdip.Graphics_DrawRectangle(graphics, selPen, x + left, y, run.x + run.width - left - 1, lineHeight - 1); - Gdip.Pen_delete(selPen); - Gdip.Graphics_Restore(graphics, gstate); - } else { - Gdip.Graphics_DrawRectangle(graphics, pen, x + left, y, run.x + run.width - left - 1, lineHeight - 1); - } - Gdip.Graphics_SetPixelOffsetMode(graphics, Gdip.PixelOffsetModeHalf); - Gdip.Pen_delete(pen); - if (brush != selectionColor && brush != color) Gdip.SolidBrush_delete(brush); - return null; - } - return clipRect; -} - -void drawRunBackground(StyleItem run, int /*long*/ hdc, RECT rect, int selectionStart, int selectionEnd, int /*long*/ selBrush, boolean hasSelection) { - int end = run.start + run.length - 1; - boolean fullSelection = hasSelection && selectionStart <= run.start && selectionEnd >= end; - if (fullSelection) { - OS.SelectObject(hdc, selBrush); - OS.PatBlt(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, OS.PATCOPY); - } else { - if (run.style != null && run.style.background != null) { - int bg = run.style.background.handle; - int /*long*/ hBrush = OS.CreateSolidBrush (bg); - int /*long*/ oldBrush = OS.SelectObject(hdc, hBrush); - OS.PatBlt(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, OS.PATCOPY); - OS.SelectObject(hdc, oldBrush); - OS.DeleteObject(hBrush); - } - boolean partialSelection = hasSelection && !(selectionStart > end || run.start > selectionEnd); - if (partialSelection) { - getPartialSelection(run, selectionStart, selectionEnd, rect); - OS.SelectObject(hdc, selBrush); - OS.PatBlt(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, OS.PATCOPY); - } - } -} - -void drawRunBackgroundGDIP(StyleItem run, int /*long*/ graphics, RECT rect, int selectionStart, int selectionEnd, int alpha, int /*long*/ selBrush, boolean hasSelection) { - int end = run.start + run.length - 1; - boolean fullSelection = hasSelection && selectionStart <= run.start && selectionEnd >= end; - if (fullSelection) { - Gdip.Graphics_FillRectangle(graphics, selBrush, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); - } else { - if (run.style != null && run.style.background != null) { - int /*long*/ brush = createGdipBrush(run.style.background, alpha); - Gdip.Graphics_FillRectangle(graphics, brush, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); - Gdip.SolidBrush_delete(brush); - } - boolean partialSelection = hasSelection && !(selectionStart > end || run.start > selectionEnd); - if (partialSelection) { - getPartialSelection(run, selectionStart, selectionEnd, rect); - if (rect.left > rect.right) { - int tmp = rect.left; - rect.left = rect.right; - rect.right = tmp; - } - Gdip.Graphics_FillRectangle(graphics, selBrush, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); - } - } -} - -RECT drawRunText(int /*long*/ hdc, StyleItem run, RECT rect, int baseline, int color, int selectionColor, int selectionStart, int selectionEnd) { - int end = run.start + run.length - 1; - boolean hasSelection = selectionStart <= selectionEnd && selectionStart != -1 && selectionEnd != -1; - boolean fullSelection = hasSelection && selectionStart <= run.start && selectionEnd >= end; - boolean partialSelection = hasSelection && !fullSelection && !(selectionStart > end || run.start > selectionEnd); - int offset = (orientation & SWT.RIGHT_TO_LEFT) != 0 ? -1 : 0; - int x = rect.left + offset; - int y = rect.top + (baseline - run.ascent); - int /*long*/ hFont = getItemFont(run); - OS.SelectObject(hdc, hFont); - if (fullSelection) { - color = selectionColor; - } else { - if (run.style != null && run.style.foreground != null) { - color = run.style.foreground.handle; - } - } - OS.SetTextColor(hdc, color); - OS.ScriptTextOut(hdc, run.psc, x, y, 0, null, run.analysis , 0, 0, run.glyphs, run.glyphCount, run.advances, run.justify, run.goffsets); - if (partialSelection) { - getPartialSelection(run, selectionStart, selectionEnd, rect); - OS.SetTextColor(hdc, selectionColor); - OS.ScriptTextOut(hdc, run.psc, x, y, OS.ETO_CLIPPED, rect, run.analysis , 0, 0, run.glyphs, run.glyphCount, run.advances, run.justify, run.goffsets); - } - return fullSelection || partialSelection ? rect : null; -} - -RECT drawRunTextGDIP(int /*long*/ graphics, StyleItem run, RECT rect, int /*long*/ gdipFont, int baseline, int /*long*/ color, int /*long*/ selectionColor, int selectionStart, int selectionEnd, int alpha) { - int end = run.start + run.length - 1; - boolean hasSelection = selectionStart <= selectionEnd && selectionStart != -1 && selectionEnd != -1; - boolean fullSelection = hasSelection && selectionStart <= run.start && selectionEnd >= end; - boolean partialSelection = hasSelection && !fullSelection && !(selectionStart > end || run.start > selectionEnd); - int drawY = rect.top + baseline; - int drawX = rect.left; - int /*long*/ brush = color; - if (fullSelection) { - brush = selectionColor; - } else { - if (run.style != null && run.style.foreground != null) { - brush = createGdipBrush(run.style.foreground, alpha); - } - } - int gstate = 0; - Rect gdipRect = null; - if (partialSelection) { - gdipRect = new Rect(); - getPartialSelection(run, selectionStart, selectionEnd, rect); - gdipRect.X = rect.left; - gdipRect.Y = rect.top; - gdipRect.Width = rect.right - rect.left; - gdipRect.Height = rect.bottom - rect.top; - gstate = Gdip.Graphics_Save(graphics); - Gdip.Graphics_SetClip(graphics, gdipRect, Gdip.CombineModeExclude); - } - int gstateMirrored = 0; - boolean isMirrored = (orientation & SWT.RIGHT_TO_LEFT) != 0; - if (isMirrored) { - switch (Gdip.Brush_GetType(brush)) { - case Gdip.BrushTypeLinearGradient: - Gdip.LinearGradientBrush_ScaleTransform(brush, -1, 1, Gdip.MatrixOrderPrepend); - Gdip.LinearGradientBrush_TranslateTransform(brush, -2 * drawX - run.width, 0, Gdip.MatrixOrderPrepend); - break; - case Gdip.BrushTypeTextureFill: - Gdip.TextureBrush_ScaleTransform(brush, -1, 1, Gdip.MatrixOrderPrepend); - Gdip.TextureBrush_TranslateTransform(brush, -2 * drawX - run.width, 0, Gdip.MatrixOrderPrepend); - break; - } - gstateMirrored = Gdip.Graphics_Save(graphics); - Gdip.Graphics_ScaleTransform(graphics, -1, 1, Gdip.MatrixOrderPrepend); - Gdip.Graphics_TranslateTransform(graphics, -2 * drawX - run.width, 0, Gdip.MatrixOrderPrepend); - } - int[] advances = new int[run.glyphCount]; - float[] points = new float[run.glyphCount * 2]; - OS.memmove(advances, run.justify != 0 ? run.justify : run.advances, run.glyphCount * 4); - int glyphX = drawX; - for (int h = 0, j = 0; h < advances.length; h++) { - points[j++] = glyphX; - points[j++] = drawY; - glyphX += advances[h]; - } - Gdip.Graphics_DrawDriverString(graphics, run.glyphs, run.glyphCount, gdipFont, brush, points, 0, 0); - if (partialSelection) { - if (isMirrored) { - Gdip.Graphics_Restore(graphics, gstateMirrored); - } - Gdip.Graphics_Restore(graphics, gstate); - gstate = Gdip.Graphics_Save(graphics); - Gdip.Graphics_SetClip(graphics, gdipRect, Gdip.CombineModeIntersect); - if (isMirrored) { - gstateMirrored = Gdip.Graphics_Save(graphics); - Gdip.Graphics_ScaleTransform(graphics, -1, 1, Gdip.MatrixOrderPrepend); - Gdip.Graphics_TranslateTransform(graphics, -2 * drawX - run.width, 0, Gdip.MatrixOrderPrepend); - } - Gdip.Graphics_DrawDriverString(graphics, run.glyphs, run.glyphCount, gdipFont, selectionColor, points, 0, 0); - Gdip.Graphics_Restore(graphics, gstate); - } - if (isMirrored) { - switch (Gdip.Brush_GetType(brush)) { - case Gdip.BrushTypeLinearGradient: - Gdip.LinearGradientBrush_ResetTransform(brush); - break; - case Gdip.BrushTypeTextureFill: - Gdip.TextureBrush_ResetTransform(brush); - break; - } - Gdip.Graphics_Restore(graphics, gstateMirrored); - } - if (brush != selectionColor && brush != color) Gdip.SolidBrush_delete(brush); - return fullSelection || partialSelection ? rect : null; -} - -RECT drawRunTextGDIPRaster(int /*long*/ graphics, StyleItem run, RECT rect, int baseline, int color, int selectionColor, int selectionStart, int selectionEnd) { - int /*long*/ clipRgn = 0; - Gdip.Graphics_SetPixelOffsetMode(graphics, Gdip.PixelOffsetModeNone); - int /*long*/ rgn = Gdip.Region_new(); - if (rgn == 0) SWT.error(SWT.ERROR_NO_HANDLES); - Gdip.Graphics_GetClip(graphics, rgn); - if (!Gdip.Region_IsInfinite(rgn, graphics)) { - clipRgn = Gdip.Region_GetHRGN(rgn, graphics); - } - Gdip.Region_delete(rgn); - Gdip.Graphics_SetPixelOffsetMode(graphics, Gdip.PixelOffsetModeHalf); - float[] lpXform = null; - int /*long*/ matrix = Gdip.Matrix_new(1, 0, 0, 1, 0, 0); - if (matrix == 0) SWT.error(SWT.ERROR_NO_HANDLES); - Gdip.Graphics_GetTransform(graphics, matrix); - if (!Gdip.Matrix_IsIdentity(matrix)) { - lpXform = new float[6]; - Gdip.Matrix_GetElements(matrix, lpXform); - } - Gdip.Matrix_delete(matrix); - int /*long*/ hdc = Gdip.Graphics_GetHDC(graphics); - int state = OS.SaveDC(hdc); - if (lpXform != null) { - OS.SetGraphicsMode(hdc, OS.GM_ADVANCED); - OS.SetWorldTransform(hdc, lpXform); - } - if (clipRgn != 0) { - OS.SelectClipRgn(hdc, clipRgn); - OS.DeleteObject(clipRgn); - } - if ((orientation & SWT.RIGHT_TO_LEFT) != 0) { - OS.SetLayout(hdc, OS.GetLayout(hdc) | OS.LAYOUT_RTL); - } - OS.SetBkMode(hdc, OS.TRANSPARENT); - RECT pRect = drawRunText(hdc, run, rect, baseline, color, selectionColor, selectionStart, selectionEnd); - OS.RestoreDC(hdc, state); - Gdip.Graphics_ReleaseHDC(graphics, hdc); - return pRect; -} - -RECT drawStrikeout(int /*long*/ hdc, int x, int baseline, StyleItem[] line, int index, int color, int selectionColor, RECT clipRect, RECT pRect, int selectionStart, int selectionEnd) { - StyleItem run = line[index]; - TextStyle style = run.style; - if (style == null) return null; - if (!style.strikeout) return null; - clipRect = addClipRect(run, clipRect, pRect, selectionStart, selectionEnd); - if (index + 1 >= line.length || !style.isAdherentStrikeout(line[index + 1].style)) { - int left = run.x; - int start = run.start; - int end = run.start + run.length - 1; - for (int i = index; i > 0 && style.isAdherentStrikeout(line[i - 1].style); i--) { - left = line[i - 1].x; - start = Math.min(start, line[i - 1].start); - end = Math.max(end, line[i - 1].start + line[i - 1].length - 1); - } - boolean hasSelection = selectionStart <= selectionEnd && selectionStart != -1 && selectionEnd != -1; - boolean fullSelection = hasSelection && selectionStart <= start && end <= selectionEnd; - if (style.strikeoutColor != null) { - color = style.strikeoutColor.handle; - clipRect = null; - } else { - if (fullSelection) { - color = selectionColor; - clipRect = null; - } else { - if (style.foreground != null) { - color = style.foreground.handle; - } - } - } - RECT rect = new RECT(); - OS.SetRect(rect, x + left, baseline - run.strikeoutPos, x + run.x + run.width, baseline - run.strikeoutPos + run.strikeoutThickness); - int /*long*/ brush = OS.CreateSolidBrush(color); - OS.FillRect(hdc, rect, brush); - OS.DeleteObject(brush); - if (clipRect != null) { - int /*long*/ selBrush = OS.CreateSolidBrush(selectionColor); - if (clipRect.left == -1) clipRect.left = 0; - if (clipRect.right == -1) clipRect.right = 0x7ffff; - OS.SetRect(clipRect, Math.max(rect.left, clipRect.left), rect.top, Math.min(rect.right, clipRect.right), rect.bottom); - OS.FillRect(hdc, clipRect, selBrush); - OS.DeleteObject(selBrush); - } - return null; - } - return clipRect; -} - -RECT drawStrikeoutGDIP(int /*long*/ graphics, int x, int baseline, StyleItem[] line, int index, int /*long*/ color, int /*long*/ selectionColor, RECT clipRect, RECT pRect, int selectionStart, int selectionEnd, int alpha) { - StyleItem run = line[index]; - TextStyle style = run.style; - if (style == null) return null; - if (!style.strikeout) return null; - clipRect = addClipRect(run, clipRect, pRect, selectionStart, selectionEnd); - if (index + 1 >= line.length || !style.isAdherentStrikeout(line[index + 1].style)) { - int left = run.x; - int start = run.start; - int end = run.start + run.length - 1; - for (int i = index; i > 0 && style.isAdherentStrikeout(line[i - 1].style); i--) { - left = line[i - 1].x; - start = Math.min(start, line[i - 1].start); - end = Math.max(end, line[i - 1].start + line[i - 1].length - 1); - } - boolean hasSelection = selectionStart <= selectionEnd && selectionStart != -1 && selectionEnd != -1; - boolean fullSelection = hasSelection && selectionStart <= start && end <= selectionEnd; - int /*long*/ brush = color; - if (style.strikeoutColor != null) { - brush = createGdipBrush(style.strikeoutColor, alpha); - clipRect = null; - } else { - if (fullSelection) { - color = selectionColor; - clipRect = null; - } else { - if (style.foreground != null) { - brush = createGdipBrush(style.foreground, alpha); - } - } - } - if (clipRect != null) { - int gstate = Gdip.Graphics_Save(graphics); - if (clipRect.left == -1) clipRect.left = 0; - if (clipRect.right == -1) clipRect.right = 0x7ffff; - Rect gdipRect = new Rect(); - gdipRect.X = clipRect.left; - gdipRect.Y = clipRect.top; - gdipRect.Width = clipRect.right - clipRect.left; - gdipRect.Height = clipRect.bottom - clipRect.top; - Gdip.Graphics_SetClip(graphics, gdipRect, Gdip.CombineModeExclude); - Gdip.Graphics_FillRectangle(graphics, brush, x + left, baseline - run.strikeoutPos, run.x + run.width - left, run.strikeoutThickness); - Gdip.Graphics_Restore(graphics, gstate); - gstate = Gdip.Graphics_Save(graphics); - Gdip.Graphics_SetClip(graphics, gdipRect, Gdip.CombineModeIntersect); - Gdip.Graphics_FillRectangle(graphics, selectionColor, x + left, baseline - run.strikeoutPos, run.x + run.width - left, run.strikeoutThickness); - Gdip.Graphics_Restore(graphics, gstate); - } else { - Gdip.Graphics_FillRectangle(graphics, brush, x + left, baseline - run.strikeoutPos, run.x + run.width - left, run.strikeoutThickness); - } - if (brush != selectionColor && brush != color) Gdip.SolidBrush_delete(brush); - return null; - } - return clipRect; -} - -RECT drawUnderline(int /*long*/ hdc, int x, int baseline, int lineUnderlinePos, int lineBottom, StyleItem[] line, int index, int color, int selectionColor, RECT clipRect, RECT pRect, int selectionStart, int selectionEnd) { - StyleItem run = line[index]; - TextStyle style = run.style; - if (style == null) return null; - if (!style.underline) return null; - clipRect = addClipRect(run, clipRect, pRect, selectionStart, selectionEnd); - if (index + 1 >= line.length || !style.isAdherentUnderline(line[index + 1].style)) { - int left = run.x; - int start = run.start; - int end = run.start + run.length - 1; - for (int i = index; i > 0 && style.isAdherentUnderline(line[i - 1].style); i--) { - left = line[i - 1].x; - start = Math.min(start, line[i - 1].start); - end = Math.max(end, line[i - 1].start + line[i - 1].length - 1); - } - boolean hasSelection = selectionStart <= selectionEnd && selectionStart != -1 && selectionEnd != -1; - boolean fullSelection = hasSelection && selectionStart <= start && end <= selectionEnd; - if (style.underlineColor != null) { - color = style.underlineColor.handle; - clipRect = null; - } else { - if (fullSelection) { - color = selectionColor; - clipRect = null; - } else { - if (style.foreground != null) { - color = style.foreground.handle; - } - } - } - RECT rect = new RECT(); - OS.SetRect(rect, x + left, baseline - lineUnderlinePos, x + run.x + run.width, baseline - lineUnderlinePos + run.underlineThickness); - if (clipRect != null) { - if (clipRect.left == -1) clipRect.left = 0; - if (clipRect.right == -1) clipRect.right = 0x7ffff; - OS.SetRect(clipRect, Math.max(rect.left, clipRect.left), rect.top, Math.min(rect.right, clipRect.right), rect.bottom); - } - switch (style.underlineStyle) { - case SWT.UNDERLINE_SQUIGGLE: - case SWT.UNDERLINE_ERROR: { - int squigglyThickness = 1; - int squigglyHeight = 2 * squigglyThickness; - int squigglyY = Math.min(rect.top - squigglyHeight / 2, lineBottom - squigglyHeight - 1); - int[] points = computePolyline(rect.left, squigglyY, rect.right, squigglyY + squigglyHeight); - int /*long*/ pen = OS.CreatePen(OS.PS_SOLID, squigglyThickness, color); - int /*long*/ oldPen = OS.SelectObject(hdc, pen); - int state = OS.SaveDC(hdc); - OS.IntersectClipRect(hdc, rect.left, squigglyY, rect.right + 1, squigglyY + squigglyHeight + 1); - OS.Polyline(hdc, points, points.length / 2); - int length = points.length; - if (length >= 2 && squigglyThickness <= 1) { - OS.SetPixel (hdc, points[length - 2], points[length - 1], color); - } - OS.SelectObject(hdc, oldPen); - OS.DeleteObject(pen); - OS.RestoreDC(hdc, state); - if (clipRect != null) { - pen = OS.CreatePen(OS.PS_SOLID, squigglyThickness, selectionColor); - oldPen = OS.SelectObject(hdc, pen); - state = OS.SaveDC(hdc); - OS.IntersectClipRect(hdc, clipRect.left, squigglyY, clipRect.right + 1, squigglyY + squigglyHeight + 1); - OS.Polyline(hdc, points, points.length / 2); - if (length >= 2 && squigglyThickness <= 1) { - OS.SetPixel (hdc, points[length - 2], points[length - 1], selectionColor); - } - OS.SelectObject(hdc, oldPen); - OS.DeleteObject(pen); - OS.RestoreDC(hdc, state); - } - break; - } - case SWT.UNDERLINE_SINGLE: - case SWT.UNDERLINE_DOUBLE: - case SWT.UNDERLINE_LINK: - case UNDERLINE_IME_THICK: - if (style.underlineStyle == UNDERLINE_IME_THICK) { - rect.top -= run.underlineThickness; - if (clipRect != null) clipRect.top -= run.underlineThickness; - } - int bottom = style.underlineStyle == SWT.UNDERLINE_DOUBLE ? rect.bottom + run.underlineThickness * 2 : rect.bottom; - if (bottom > lineBottom) { - OS.OffsetRect(rect, 0, lineBottom - bottom); - if (clipRect != null) OS.OffsetRect(clipRect, 0, lineBottom - bottom); - } - int /*long*/ brush = OS.CreateSolidBrush(color); - OS.FillRect(hdc, rect, brush); - if (style.underlineStyle == SWT.UNDERLINE_DOUBLE) { - OS.SetRect(rect, rect.left, rect.top + run.underlineThickness * 2, rect.right, rect.bottom + run.underlineThickness * 2); - OS.FillRect(hdc, rect, brush); - } - OS.DeleteObject(brush); - if (clipRect != null) { - int /*long*/ selBrush = OS.CreateSolidBrush(selectionColor); - OS.FillRect(hdc, clipRect, selBrush); - if (style.underlineStyle == SWT.UNDERLINE_DOUBLE) { - OS.SetRect(clipRect, clipRect.left, rect.top, clipRect.right, rect.bottom); - OS.FillRect(hdc, clipRect, selBrush); - } - OS.DeleteObject(selBrush); - } - break; - case UNDERLINE_IME_DASH: - case UNDERLINE_IME_DOT: { - int penStyle = style.underlineStyle == UNDERLINE_IME_DASH ? OS.PS_DASH : OS.PS_DOT; - int /*long*/ pen = OS.CreatePen(penStyle, 1, color); - int /*long*/ oldPen = OS.SelectObject(hdc, pen); - OS.SetRect(rect, rect.left, baseline + run.descent, rect.right, baseline + run.descent + run.underlineThickness); - OS.MoveToEx(hdc, rect.left, rect.top, 0); - OS.LineTo(hdc, rect.right, rect.top); - OS.SelectObject(hdc, oldPen); - OS.DeleteObject(pen); - if (clipRect != null) { - pen = OS.CreatePen(penStyle, 1, selectionColor); - oldPen = OS.SelectObject(hdc, pen); - OS.SetRect(clipRect, clipRect.left, rect.top, clipRect.right, rect.bottom); - OS.MoveToEx(hdc, clipRect.left, clipRect.top, 0); - OS.LineTo(hdc, clipRect.right, clipRect.top); - OS.SelectObject(hdc, oldPen); - OS.DeleteObject(pen); - } - break; - } - } - return null; - } - return clipRect; -} - -RECT drawUnderlineGDIP (int /*long*/ graphics, int x, int baseline, int lineUnderlinePos, int lineBottom, StyleItem[] line, int index, int /*long*/ color, int /*long*/ selectionColor, RECT clipRect, RECT pRect, int selectionStart, int selectionEnd, int alpha) { - StyleItem run = line[index]; - TextStyle style = run.style; - if (style == null) return null; - if (!style.underline) return null; - clipRect = addClipRect(run, clipRect, pRect, selectionStart, selectionEnd); - if (index + 1 >= line.length || !style.isAdherentUnderline(line[index + 1].style)) { - int left = run.x; - int start = run.start; - int end = run.start + run.length - 1; - for (int i = index; i > 0 && style.isAdherentUnderline(line[i - 1].style); i--) { - left = line[i - 1].x; - start = Math.min(start, line[i - 1].start); - end = Math.max(end, line[i - 1].start + line[i - 1].length - 1); - } - boolean hasSelection = selectionStart <= selectionEnd && selectionStart != -1 && selectionEnd != -1; - boolean fullSelection = hasSelection && selectionStart <= start && end <= selectionEnd; - int /*long*/ brush = color; - if (style.underlineColor != null) { - brush = createGdipBrush(style.underlineColor, alpha); - clipRect = null; - } else { - if (fullSelection) { - brush = selectionColor; - clipRect = null; - } else { - if (style.foreground != null) { - brush = createGdipBrush(style.foreground, alpha); - } - } - } - RECT rect = new RECT(); - OS.SetRect(rect, x + left, baseline - lineUnderlinePos, x + run.x + run.width, baseline - lineUnderlinePos + run.underlineThickness); - Rect gdipRect = null; - if (clipRect != null) { - if (clipRect.left == -1) clipRect.left = 0; - if (clipRect.right == -1) clipRect.right = 0x7ffff; - OS.SetRect(clipRect, Math.max(rect.left, clipRect.left), rect.top, Math.min(rect.right, clipRect.right), rect.bottom); - gdipRect = new Rect(); - gdipRect.X = clipRect.left; - gdipRect.Y = clipRect.top; - gdipRect.Width = clipRect.right - clipRect.left; - gdipRect.Height = clipRect.bottom - clipRect.top; - } - int gstate = 0; - Gdip.Graphics_SetPixelOffsetMode(graphics, Gdip.PixelOffsetModeNone); - switch (style.underlineStyle) { - case SWT.UNDERLINE_SQUIGGLE: - case SWT.UNDERLINE_ERROR: { - int squigglyThickness = 1; - int squigglyHeight = 2 * squigglyThickness; - int squigglyY = Math.min(rect.top - squigglyHeight / 2, lineBottom - squigglyHeight - 1); - int[] points = computePolyline(rect.left, squigglyY, rect.right, squigglyY + squigglyHeight); - int /*long*/ pen = Gdip.Pen_new(brush, squigglyThickness); - gstate = Gdip.Graphics_Save(graphics); - if (gdipRect != null) { - Gdip.Graphics_SetClip(graphics, gdipRect, Gdip.CombineModeExclude); - } else { - Rect r = new Rect(); - r.X = rect.left; - r.Y = squigglyY; - r.Width = rect.right - rect.left; - r.Height = squigglyHeight + 1; - Gdip.Graphics_SetClip(graphics, r, Gdip.CombineModeIntersect); - } - Gdip.Graphics_DrawLines(graphics, pen, points, points.length / 2); - if (gdipRect != null) { - int /*long*/ selPen = Gdip.Pen_new(selectionColor, squigglyThickness); - Gdip.Graphics_Restore(graphics, gstate); - gstate = Gdip.Graphics_Save(graphics); - Gdip.Graphics_SetClip(graphics, gdipRect, Gdip.CombineModeIntersect); - Gdip.Graphics_DrawLines(graphics, selPen, points, points.length / 2); - Gdip.Pen_delete(selPen); - } - Gdip.Graphics_Restore(graphics, gstate); - Gdip.Pen_delete(pen); - if (gstate != 0) Gdip.Graphics_Restore(graphics, gstate); - break; - } - case SWT.UNDERLINE_SINGLE: - case SWT.UNDERLINE_DOUBLE: - case SWT.UNDERLINE_LINK: - case UNDERLINE_IME_THICK: - if (style.underlineStyle == UNDERLINE_IME_THICK) { - rect.top -= run.underlineThickness; - } - int bottom = style.underlineStyle == SWT.UNDERLINE_DOUBLE ? rect.bottom + run.underlineThickness * 2 : rect.bottom; - if (bottom > lineBottom) { - OS.OffsetRect(rect, 0, lineBottom - bottom); - } - if (gdipRect != null) { - gdipRect.Y = rect.top; - if (style.underlineStyle == UNDERLINE_IME_THICK) { - gdipRect.Height = run.underlineThickness * 2; - } - if (style.underlineStyle == SWT.UNDERLINE_DOUBLE) { - gdipRect.Height = run.underlineThickness * 3; - } - gstate = Gdip.Graphics_Save(graphics); - Gdip.Graphics_SetClip(graphics, gdipRect, Gdip.CombineModeExclude); - } - Gdip.Graphics_FillRectangle(graphics, brush, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); - if (style.underlineStyle == SWT.UNDERLINE_DOUBLE) { - Gdip.Graphics_FillRectangle(graphics, brush, rect.left, rect.top + run.underlineThickness * 2, rect.right - rect.left, rect.bottom - rect.top); - } - if (gdipRect != null) { - Gdip.Graphics_Restore(graphics, gstate); - gstate = Gdip.Graphics_Save(graphics); - Gdip.Graphics_SetClip(graphics, gdipRect, Gdip.CombineModeIntersect); - Gdip.Graphics_FillRectangle(graphics, selectionColor, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); - if (style.underlineStyle == SWT.UNDERLINE_DOUBLE) { - Gdip.Graphics_FillRectangle(graphics, selectionColor, rect.left, rect.top + run.underlineThickness * 2, rect.right - rect.left, rect.bottom - rect.top); - } - Gdip.Graphics_Restore(graphics, gstate); - } - break; - case UNDERLINE_IME_DOT: - case UNDERLINE_IME_DASH: { - int /*long*/ pen = Gdip.Pen_new(brush, 1); - int dashStyle = style.underlineStyle == UNDERLINE_IME_DOT ? Gdip.DashStyleDot : Gdip.DashStyleDash; - Gdip.Pen_SetDashStyle(pen, dashStyle); - if (gdipRect != null) { - gstate = Gdip.Graphics_Save(graphics); - Gdip.Graphics_SetClip(graphics, gdipRect, Gdip.CombineModeExclude); - } - Gdip.Graphics_DrawLine(graphics, pen, rect.left, baseline + run.descent, run.width - run.length, baseline + run.descent); - if (gdipRect != null) { - Gdip.Graphics_Restore(graphics, gstate); - gstate = Gdip.Graphics_Save(graphics); - Gdip.Graphics_SetClip(graphics, gdipRect, Gdip.CombineModeIntersect); - int /*long*/ selPen = Gdip.Pen_new(brush, 1); - Gdip.Pen_SetDashStyle(selPen, dashStyle); - Gdip.Graphics_DrawLine(graphics, selPen, rect.left, baseline + run.descent, run.width - run.length, baseline + run.descent); - Gdip.Graphics_Restore(graphics, gstate); - Gdip.Pen_delete(selPen); - } - Gdip.Pen_delete(pen); - break; - } - } - if (brush != selectionColor && brush != color) Gdip.SolidBrush_delete(brush); - Gdip.Graphics_SetPixelOffsetMode(graphics, Gdip.PixelOffsetModeHalf); - return null; - } - return clipRect; -} - -void freeRuns () { - if (allRuns == null) return; - for (int i=0; i<allRuns.length; i++) { - StyleItem run = allRuns[i]; - run.free(); - } - allRuns = null; - runs = null; - segmentsText = 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(); - return alignment; -} - -/** - * 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(null); - int width = 0; - if (wrapWidth != -1) { - width = wrapWidth; - } else { - for (int line=0; line<runs.length; line++) { - width = Math.max(width, lineWidth[line] + getLineIndent(line)); - } - } - return new Rectangle (0, 0, width, lineY[lineY.length - 1]); -} - -/** - * 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(null); - 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); - int left = 0x7fffffff, right = 0; - int top = 0x7fffffff, bottom = 0; - boolean isRTL = (orientation & SWT.RIGHT_TO_LEFT) != 0; - for (int i = 0; i < allRuns.length - 1; i++) { - StyleItem run = allRuns[i]; - int runEnd = run.start + run.length; - if (runEnd <= start) continue; - if (run.start > end) break; - int runLead = run.x; - int runTrail = run.x + run.width; - if (run.start <= start && start < runEnd) { - int cx = 0; - if (run.style != null && run.style.metrics != null) { - GlyphMetrics metrics = run.style.metrics; - cx = metrics.width * (start - run.start); - } else if (!run.tab) { - int[] piX = new int[1]; - int /*long*/ advances = run.justify != 0 ? run.justify : run.advances; - OS.ScriptCPtoX(start - run.start, false, run.length, run.glyphCount, run.clusters, run.visAttrs, advances, run.analysis, piX); - cx = isRTL ? run.width - piX[0] : piX[0]; - } - if (run.analysis.fRTL ^ isRTL) { - runTrail = run.x + cx; - } else { - runLead = run.x + cx; - } - } - if (run.start <= end && end < runEnd) { - int cx = run.width; - if (run.style != null && run.style.metrics != null) { - GlyphMetrics metrics = run.style.metrics; - cx = metrics.width * (end - run.start + 1); - } else if (!run.tab) { - int[] piX = new int[1]; - int /*long*/ advances = run.justify != 0 ? run.justify : run.advances; - OS.ScriptCPtoX(end - run.start, true, run.length, run.glyphCount, run.clusters, run.visAttrs, advances, run.analysis, piX); - cx = isRTL ? run.width - piX[0] : piX[0]; - } - if (run.analysis.fRTL ^ isRTL) { - runLead = run.x + cx; - } else { - runTrail = run.x + cx; - } - } - int lineIndex = 0; - while (lineIndex < runs.length && lineOffset[lineIndex + 1] <= run.start) { - lineIndex++; - } - left = Math.min(left, runLead); - right = Math.max(right, runTrail); - top = Math.min(top, lineY[lineIndex]); - bottom = Math.max(bottom, lineY[lineIndex + 1] - lineSpacing); - } - return new Rectangle(left, top, right - left, bottom - 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(); - return justify; -} - -int /*long*/ getItemFont (StyleItem item) { - if (item.fallbackFont != 0) return item.fallbackFont; - if (item.style != null && item.style.font != null) { - return item.style.font.handle; - } - if (this.font != null) { - return this.font.handle; - } - return device.systemFont.handle; -} - -/** - * 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(null); - int length = text.length(); - if (!(0 <= offset && offset <= length)) SWT.error(SWT.ERROR_INVALID_RANGE); - offset = translateOffset(offset); - for (int i=1; i<allRuns.length; i++) { - if (allRuns[i].start > offset) { - return allRuns[i - 1].analysis.s.uBidiLevel; - } - } - return (orientation & SWT.RIGHT_TO_LEFT) != 0 ? 1 : 0; -} - -/** - * 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(null); - if (!(0 <= lineIndex && lineIndex < runs.length)) SWT.error(SWT.ERROR_INVALID_RANGE); - int x = getLineIndent(lineIndex); - int y = lineY[lineIndex]; - int width = lineWidth[lineIndex]; - int height = lineY[lineIndex + 1] - y - lineSpacing; - return new Rectangle (x, y, width, height); -} - -/** - * 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(null); - return runs.length; -} - -int getLineIndent (int lineIndex) { - int lineIndent = 0; - if (lineIndex == 0) { - lineIndent = indent; - } else { - StyleItem[] previousLine = runs[lineIndex - 1]; - StyleItem previousRun = previousLine[previousLine.length - 1]; - if (previousRun.lineBreak && !previousRun.softBreak) { - lineIndent = indent; - } - } - if (wrapWidth != -1) { - boolean partialLine = true; - if (justify) { - StyleItem[] lineRun = runs[lineIndex]; - if (lineRun[lineRun.length - 1].softBreak) { - partialLine = false; - } - } - if (partialLine) { - int lineWidth = this.lineWidth[lineIndex] + lineIndent; - switch (alignment) { - case SWT.CENTER: lineIndent += (wrapWidth - lineWidth) / 2; break; - case SWT.RIGHT: lineIndent += wrapWidth - lineWidth; break; - } - } - } - return lineIndent; -} - -/** - * 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(null); - int length = text.length(); - if (!(0 <= offset && offset <= length)) SWT.error(SWT.ERROR_INVALID_RANGE); - offset = translateOffset(offset); - for (int line=0; line<runs.length; line++) { - if (lineOffset[line + 1] > offset) { - return line; - } - } - return runs.length - 1; -} - -/** - * 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(null); - if (!(0 <= lineIndex && lineIndex < runs.length)) SWT.error(SWT.ERROR_INVALID_RANGE); - int /*long*/ hDC = device.internal_new_GC(null); - int /*long*/ srcHdc = OS.CreateCompatibleDC(hDC); - TEXTMETRIC lptm = OS.IsUnicode ? (TEXTMETRIC)new TEXTMETRICW() : new TEXTMETRICA(); - OS.SelectObject(srcHdc, font != null ? font.handle : device.systemFont.handle); - OS.GetTextMetrics(srcHdc, lptm); - OS.DeleteDC(srcHdc); - device.internal_dispose_GC(hDC, null); - - int ascent = Math.max(lptm.tmAscent, this.ascent); - int descent = Math.max(lptm.tmDescent, this.descent); - int leading = lptm.tmInternalLeading; - if (text.length() != 0) { - StyleItem[] lineRuns = runs[lineIndex]; - for (int i = 0; i<lineRuns.length; i++) { - StyleItem run = lineRuns[i]; - if (run.ascent > ascent) { - ascent = run.ascent; - leading = run.leading; - } - descent = Math.max(descent, run.descent); - } - } - lptm.tmAscent = ascent; - lptm.tmDescent = descent; - lptm.tmHeight = ascent + descent; - lptm.tmInternalLeading = leading; - lptm.tmAveCharWidth = 0; - return FontMetrics.win32_new(lptm); -} - -/** - * 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(null); - int[] offsets = new int[lineOffset.length]; - for (int i = 0; i < offsets.length; i++) { - offsets[i] = untranslateOffset(lineOffset[i]); - } - return offsets; -} - -/** - * 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(null); - int length = text.length(); - if (!(0 <= offset && offset <= length)) SWT.error(SWT.ERROR_INVALID_RANGE); - length = segmentsText.length(); - offset = translateOffset(offset); - int line; - for (line=0; line<runs.length; line++) { - if (lineOffset[line + 1] > offset) break; - } - line = Math.min(line, runs.length - 1); - if (offset == length) { - return new Point(getLineIndent(line) + lineWidth[line], lineY[line]); - } - int low = -1; - int high = allRuns.length; - while (high - low > 1) { - int index = ((high + low) / 2); - StyleItem run = allRuns[index]; - if (run.start > offset) { - high = index; - } else if (run.start + run.length <= offset) { - low = index; - } else { - int width; - if (run.style != null && run.style.metrics != null) { - GlyphMetrics metrics = run.style.metrics; - width = metrics.width * (offset - run.start + (trailing ? 1 : 0)); - } else if (run.tab) { - width = (trailing || (offset == length)) ? run.width : 0; - } else { - int runOffset = offset - run.start; - int cChars = run.length; - int gGlyphs = run.glyphCount; - int[] piX = new int[1]; - int /*long*/ advances = run.justify != 0 ? run.justify : run.advances; - OS.ScriptCPtoX(runOffset, trailing, cChars, gGlyphs, run.clusters, run.visAttrs, advances, run.analysis, piX); - width = (orientation & SWT.RIGHT_TO_LEFT) != 0 ? run.width - piX[0] : piX[0]; - } - return new Point(run.x + width, lineY[line]); - } - } - return new Point(0, 0); -} - -/** - * 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) { - checkLayout(); - return _getOffset (offset, movement, true); -} - -int _getOffset(int offset, int movement, boolean forward) { - computeRuns(null); - int length = text.length(); - if (!(0 <= offset && offset <= length)) SWT.error(SWT.ERROR_INVALID_RANGE); - if (forward && offset == length) return length; - if (!forward && offset == 0) return 0; - int step = forward ? 1 : -1; - if ((movement & SWT.MOVEMENT_CHAR) != 0) return offset + step; - length = segmentsText.length(); - offset = translateOffset(offset); - SCRIPT_LOGATTR logAttr = new SCRIPT_LOGATTR(); - SCRIPT_PROPERTIES properties = new SCRIPT_PROPERTIES(); - int i = forward ? 0 : allRuns.length - 1; - offset = validadeOffset(offset, step); - do { - StyleItem run = allRuns[i]; - if (run.start <= offset && offset < run.start + run.length) { - if (run.lineBreak && !run.softBreak) return untranslateOffset(run.start); - if (run.tab) return untranslateOffset(run.start); - OS.MoveMemory(properties, device.scripts[run.analysis.eScript], SCRIPT_PROPERTIES.sizeof); - boolean isComplex = properties.fNeedsCaretInfo || properties.fNeedsWordBreaking; - if (isComplex) breakRun(run); - while (run.start <= offset && offset < run.start + run.length) { - if (isComplex) { - OS.MoveMemory(logAttr, run.psla + ((offset - run.start) * SCRIPT_LOGATTR.sizeof), SCRIPT_LOGATTR.sizeof); - } - switch (movement) { - case SWT.MOVEMENT_CLUSTER: { - if (properties.fNeedsCaretInfo) { - if (!logAttr.fInvalid && logAttr.fCharStop) return untranslateOffset(offset); - } else { - return untranslateOffset(offset); - } - break; - } - case SWT.MOVEMENT_WORD_START: - case SWT.MOVEMENT_WORD: { - if (properties.fNeedsWordBreaking) { - if (!logAttr.fInvalid && logAttr.fWordStop) return untranslateOffset(offset); - } else { - if (offset > 0) { - boolean letterOrDigit = Compatibility.isLetterOrDigit(segmentsText.charAt(offset)); - boolean previousLetterOrDigit = Compatibility.isLetterOrDigit(segmentsText.charAt(offset - 1)); - if (letterOrDigit != previousLetterOrDigit || !letterOrDigit) { - if (!Compatibility.isWhitespace(segmentsText.charAt(offset))) { - return untranslateOffset(offset); - } - } - } - } - break; - } - case SWT.MOVEMENT_WORD_END: { - if (offset > 0) { - boolean isLetterOrDigit = Compatibility.isLetterOrDigit(segmentsText.charAt(offset)); - boolean previousLetterOrDigit = Compatibility.isLetterOrDigit(segmentsText.charAt(offset - 1)); - if (!isLetterOrDigit && previousLetterOrDigit) { - return untranslateOffset(offset); - } - } - break; - } - } - offset = validadeOffset(offset, step); - } - } - i += step; - } while (0 <= i && i < allRuns.length - 1 && 0 <= offset && offset < length); - return forward ? text.length() : 0; -} - -/** - * 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(); - 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(null); - if (trailing != null && trailing.length < 1) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - int line; - int lineCount = runs.length; - for (line=0; line<lineCount; line++) { - if (lineY[line + 1] > y) break; - } - line = Math.min(line, runs.length - 1); - StyleItem[] lineRuns = runs[line]; - int lineIndent = getLineIndent(line); - if (x >= lineIndent + lineWidth[line]) x = lineIndent + lineWidth[line] - 1; - if (x < lineIndent) x = lineIndent; - int low = -1; - int high = lineRuns.length; - while (high - low > 1) { - int index = ((high + low) / 2); - StyleItem run = lineRuns[index]; - if (run.x > x) { - high = index; - } else if (run.x + run.width <= x) { - low = index; - } else { - if (run.lineBreak && !run.softBreak) return untranslateOffset(run.start); - int xRun = x - run.x; - if (run.style != null && run.style.metrics != null) { - GlyphMetrics metrics = run.style.metrics; - if (metrics.width > 0) { - if (trailing != null) { - trailing[0] = (xRun % metrics.width < metrics.width / 2) ? 0 : 1; - } - return untranslateOffset(run.start + xRun / metrics.width); - } - } - if (run.tab) { - if (trailing != null) trailing[0] = x < (run.x + run.width / 2) ? 0 : 1; - return untranslateOffset(run.start); - } - int cChars = run.length; - int cGlyphs = run.glyphCount; - int[] piCP = new int[1]; - int[] piTrailing = new int[1]; - if ((orientation & SWT.RIGHT_TO_LEFT) != 0) { - xRun = run.width - xRun; - } - int /*long*/ advances = run.justify != 0 ? run.justify : run.advances; - OS.ScriptXtoCP(xRun, cChars, cGlyphs, run.clusters, run.visAttrs, advances, run.analysis, piCP, piTrailing); - if (trailing != null) trailing[0] = piTrailing[0]; - return untranslateOffset(run.start + piCP[0]); - } - } - if (trailing != null) trailing[0] = 0; - if (lineRuns.length == 1) { - StyleItem run = lineRuns[0]; - if (run.lineBreak && !run.softBreak) return untranslateOffset(run.start); - } - return untranslateOffset(lineOffset[line + 1]); -} - -/** - * 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(); - return orientation; -} - -void getPartialSelection(StyleItem run, int selectionStart, int selectionEnd, RECT rect) { - int end = run.start + run.length - 1; - int selStart = Math.max(selectionStart, run.start) - run.start; - int selEnd = Math.min(selectionEnd, end) - run.start; - int cChars = run.length; - int gGlyphs = run.glyphCount; - int[] piX = new int[1]; - int x = rect.left; - int /*long*/ advances = run.justify != 0 ? run.justify : run.advances; - OS.ScriptCPtoX(selStart, false, cChars, gGlyphs, run.clusters, run.visAttrs, advances, run.analysis, piX); - int runX = (orientation & SWT.RIGHT_TO_LEFT) != 0 ? run.width - piX[0] : piX[0]; - rect.left = x + runX; - OS.ScriptCPtoX(selEnd, true, cChars, gGlyphs, run.clusters, run.visAttrs, advances, run.analysis, piX); - runX = (orientation & SWT.RIGHT_TO_LEFT) != 0 ? run.width - piX[0] : piX[0]; - rect.right = x + runX; -} - -/** - * 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 offset, int movement) { - checkLayout(); - return _getOffset (offset, 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[stylesCount * 2]; - int count = 0; - for (int i=0; i<stylesCount - 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; - } - char[] oldChars = new char[length]; - text.getChars(0, length, oldChars, 0); - char[] newChars = new char[length + nSegments]; - int charCount = 0, segmentCount = 0; - char separator = orientation == SWT.RIGHT_TO_LEFT ? RTL_MARK : LTR_MARK; - while (charCount < length) { - if (segmentCount < nSegments && charCount == segments[segmentCount]) { - newChars[charCount + segmentCount++] = separator; - } else { - newChars[charCount + segmentCount] = oldChars[charCount++]; - } - } - if (segmentCount < nSegments) { - segments[segmentCount] = charCount; - newChars[charCount + segmentCount++] = separator; - } - 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 lineSpacing; -} - -/** - * 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<stylesCount; i++) { - if (styles[i].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[stylesCount]; - int count = 0; - for (int i=0; i<stylesCount; 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(); - return wrapWidth; -} - -/** - * 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 device == null; -} - -/* - * Itemize the receiver text - */ -StyleItem[] itemize () { - segmentsText = getSegmentsText(); - int length = segmentsText.length(); - SCRIPT_CONTROL scriptControl = new SCRIPT_CONTROL(); - SCRIPT_STATE scriptState = new SCRIPT_STATE(); - final int MAX_ITEM = length + 1; - - if ((orientation & SWT.RIGHT_TO_LEFT) != 0) { - scriptState.uBidiLevel = 1; - scriptState.fArabicNumContext = true; - SCRIPT_DIGITSUBSTITUTE psds = new SCRIPT_DIGITSUBSTITUTE(); - OS.ScriptRecordDigitSubstitution(OS.LOCALE_USER_DEFAULT, psds); - OS.ScriptApplyDigitSubstitution(psds, scriptControl, scriptState); - } - - int /*long*/ hHeap = OS.GetProcessHeap(); - int /*long*/ pItems = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, MAX_ITEM * SCRIPT_ITEM.sizeof); - if (pItems == 0) SWT.error(SWT.ERROR_NO_HANDLES); - int[] pcItems = new int[1]; - char[] chars = new char[length]; - segmentsText.getChars(0, length, chars, 0); - OS.ScriptItemize(chars, length, MAX_ITEM, scriptControl, scriptState, pItems, pcItems); -// if (hr == E_OUTOFMEMORY) //TODO handle it - - StyleItem[] runs = merge(pItems, pcItems[0]); - OS.HeapFree(hHeap, 0, pItems); - return runs; -} - -/* - * Merge styles ranges and script items - */ -StyleItem[] merge (int /*long*/ items, int itemCount) { - if (styles.length > stylesCount) { - StyleItem[] newStyles = new StyleItem[stylesCount]; - System.arraycopy(styles, 0, newStyles, 0, stylesCount); - styles = newStyles; - } - int count = 0, start = 0, end = segmentsText.length(), itemIndex = 0, styleIndex = 0; - StyleItem[] runs = new StyleItem[itemCount + stylesCount]; - SCRIPT_ITEM scriptItem = new SCRIPT_ITEM(); - int itemLimit = -1; - int nextItemIndex = 0; - boolean linkBefore = false; - boolean merge = itemCount > TOO_MANY_RUNS; - SCRIPT_PROPERTIES sp = new SCRIPT_PROPERTIES(); - while (start < end) { - StyleItem item = new StyleItem(); - item.start = start; - item.style = styles[styleIndex].style; - runs[count++] = item; - OS.MoveMemory(scriptItem, items + itemIndex * SCRIPT_ITEM.sizeof, SCRIPT_ITEM.sizeof); - item.analysis = scriptItem.a; - scriptItem.a = new SCRIPT_ANALYSIS(); - if (linkBefore) { - item.analysis.fLinkBefore = true; - linkBefore = false; - } - char ch = segmentsText.charAt(start); - switch (ch) { - case '\r': - case '\n': - item.lineBreak = true; - break; - case '\t': - item.tab = true; - break; - } - if (itemLimit == -1) { - nextItemIndex = itemIndex + 1; - OS.MoveMemory(scriptItem, items + nextItemIndex * SCRIPT_ITEM.sizeof, SCRIPT_ITEM.sizeof); - itemLimit = scriptItem.iCharPos; - if (nextItemIndex < itemCount && ch == '\r' && segmentsText.charAt(itemLimit) == '\n') { - nextItemIndex = itemIndex + 2; - OS.MoveMemory(scriptItem, items + nextItemIndex * SCRIPT_ITEM.sizeof, SCRIPT_ITEM.sizeof); - itemLimit = scriptItem.iCharPos; - } - if (nextItemIndex < itemCount && merge) { - if (!item.lineBreak) { - OS.MoveMemory(sp, device.scripts[item.analysis.eScript], SCRIPT_PROPERTIES.sizeof); - if (!sp.fComplex || item.tab) { - for (int i = 0; i < MERGE_MAX; i++) { - if (nextItemIndex == itemCount) break; - char c = segmentsText.charAt(itemLimit); - if (c == '\n' || c == '\r') break; - if (c == '\t' != item.tab) break; - OS.MoveMemory(sp, device.scripts[scriptItem.a.eScript], SCRIPT_PROPERTIES.sizeof); - if (!item.tab && sp.fComplex) break; - nextItemIndex++; - OS.MoveMemory(scriptItem, items + nextItemIndex * SCRIPT_ITEM.sizeof, SCRIPT_ITEM.sizeof); - itemLimit = scriptItem.iCharPos; - } - } - } - } - } - - int styleLimit = translateOffset(styles[styleIndex + 1].start); - if (styleLimit <= itemLimit) { - styleIndex++; - start = styleLimit; - if (start < itemLimit && 0 < start && start < end) { - char pChar = segmentsText.charAt(start - 1); - char tChar = segmentsText.charAt(start); - if (Compatibility.isLetter(pChar) && Compatibility.isLetter(tChar)) { - item.analysis.fLinkAfter = true; - linkBefore = true; - } - } - } - if (itemLimit <= styleLimit) { - itemIndex = nextItemIndex; - start = itemLimit; - itemLimit = -1; - } - item.length = start - item.start; - } - StyleItem item = new StyleItem(); - item.start = end; - OS.MoveMemory(scriptItem, items + itemCount * SCRIPT_ITEM.sizeof, SCRIPT_ITEM.sizeof); - item.analysis = scriptItem.a; - runs[count++] = item; - if (runs.length != count) { - StyleItem[] result = new StyleItem[count]; - System.arraycopy(runs, 0, result, 0, count); - return result; - } - return runs; -} - -/* - * Reorder the run - */ -StyleItem[] reorder (StyleItem[] runs, boolean terminate) { - int length = runs.length; - if (length <= 1) return runs; - byte[] bidiLevels = new byte[length]; - for (int i=0; i<length; i++) { - bidiLevels[i] = (byte)(runs[i].analysis.s.uBidiLevel & 0x1F); - } - /* - * Feature in Windows. If the orientation is RTL Uniscribe will - * resolve the level of line breaks to 1, this can cause the line - * break to be reorder to the middle of the line. The fix is to set - * the level to zero to prevent it to be reordered. - */ - StyleItem lastRun = runs[length - 1]; - if (lastRun.lineBreak && !lastRun.softBreak) { - bidiLevels[length - 1] = 0; - } - int[] log2vis = new int[length]; - OS.ScriptLayout(length, bidiLevels, null, log2vis); - StyleItem[] result = new StyleItem[length]; - for (int i=0; i<length; i++) { - result[log2vis[i]] = runs[i]; - } - if ((orientation & SWT.RIGHT_TO_LEFT) != 0) { - if (terminate) length--; - for (int i = 0; i < length / 2 ; i++) { - StyleItem tmp = result[i]; - result[i] = result[length - i - 1]; - result[length - i - 1] = tmp; - } - } - return result; -} - -/** - * 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 & SWT.LEFT) != 0) alignment = SWT.LEFT; - if ((alignment & SWT.RIGHT) != 0) alignment = SWT.RIGHT; - if (this.alignment == alignment) return; - freeRuns(); - this.alignment = alignment; -} - -/** - * 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; -} - -/** - * 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 (this.justify == justify) return; - freeRuns(); - this.justify = justify; -} - -/** - * 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.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT; - orientation &= mask; - if (orientation == 0) return; - if ((orientation & SWT.LEFT_TO_RIGHT) != 0) orientation = SWT.LEFT_TO_RIGHT; - if (this.orientation == orientation) return; - this.orientation = orientation; - freeRuns(); -} - -/** - * 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.lineSpacing == spacing) return; - freeRuns(); - this.lineSpacing = 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 = stylesCount; - while (high - low > 1) { - int index = (high + low) / 2; - if (styles[index + 1].start > start) { - high = index; - } else { - low = index; - } - } - if (0 <= high && high < stylesCount) { - 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 < stylesCount) { - 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) { - int newLength = stylesCount + 2; - if (newLength > styles.length) { - int newSize = Math.min(newLength + 1024, Math.max(64, newLength * 2)); - StyleItem[] newStyles = new StyleItem[newSize]; - System.arraycopy(styles, 0, newStyles, 0, stylesCount); - styles = newStyles; - } - System.arraycopy(styles, modifyEnd + 1, styles, modifyEnd + 3, stylesCount - modifyEnd - 1); - StyleItem item = new StyleItem(); - item.start = start; - item.style = style; - styles[modifyStart + 1] = item; - item = new StyleItem(); - item.start = end + 1; - item.style = styles[modifyStart].style; - styles[modifyStart + 2] = item; - stylesCount = newLength; - return; - } - } - if (start == styles[modifyStart].start) modifyStart--; - if (end == styles[modifyEnd + 1].start - 1) modifyEnd++; - int newLength = stylesCount + 1 - (modifyEnd - modifyStart - 1); - if (newLength > styles.length) { - int newSize = Math.min(newLength + 1024, Math.max(64, newLength * 2)); - StyleItem[] newStyles = new StyleItem[newSize]; - System.arraycopy(styles, 0, newStyles, 0, stylesCount); - styles = newStyles; - } - System.arraycopy(styles, modifyEnd, styles, modifyStart + 2, stylesCount - modifyEnd); - StyleItem item = new StyleItem(); - item.start = start; - item.style = style; - styles[modifyStart + 1] = item; - styles[modifyStart + 2].start = end + 1; - stylesCount = newLength; -} - -/** - * 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; -} - -/** - * 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[1].start = text.length(); - stylesCount = 2; -} - -/** - * 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 (this.wrapWidth == width) return; - freeRuns(); - this.wrapWidth = width; -} - -boolean shape (int /*long*/ hdc, StyleItem run, char[] chars, int[] glyphCount, int maxGlyphs, SCRIPT_PROPERTIES sp) { - boolean useCMAPcheck = !sp.fComplex && !run.analysis.fNoGlyphIndex; - if (useCMAPcheck) { - short[] glyphs = new short[chars.length]; - if (OS.ScriptGetCMap(hdc, run.psc, chars, chars.length, 0, glyphs) != OS.S_OK) { - if (run.psc != 0) { - OS.ScriptFreeCache(run.psc); - glyphCount[0] = 0; - OS.MoveMemory(run.psc, new int /*long*/ [1], OS.PTR_SIZEOF); - } - return false; - } - } - int hr = OS.ScriptShape(hdc, run.psc, chars, chars.length, maxGlyphs, run.analysis, run.glyphs, run.clusters, run.visAttrs, glyphCount); - run.glyphCount = glyphCount[0]; - if (useCMAPcheck) return true; - - if (hr != OS.USP_E_SCRIPT_NOT_IN_FONT) { - if (run.analysis.fNoGlyphIndex) return true; - SCRIPT_FONTPROPERTIES fp = new SCRIPT_FONTPROPERTIES (); - fp.cBytes = SCRIPT_FONTPROPERTIES.sizeof; - OS.ScriptGetFontProperties(hdc, run.psc, fp); - short[] glyphs = new short[glyphCount[0]]; - OS.MoveMemory(glyphs, run.glyphs, glyphs.length * 2); - int i; - for (i = 0; i < glyphs.length; i++) { - if (glyphs[i] == fp.wgDefault) break; - } - if (i == glyphs.length) return true; - } - if (run.psc != 0) { - OS.ScriptFreeCache(run.psc); - glyphCount[0] = 0; - OS.MoveMemory(run.psc, new int /*long*/ [1], OS.PTR_SIZEOF); - } - run.glyphCount = 0; - return false; -} - -/* - * Generate glyphs for one Run. - */ -void shape (final int /*long*/ hdc, final StyleItem run) { - if (run.tab || run.lineBreak) return; - if (run.glyphs != 0) return; - final int[] buffer = new int[1]; - final char[] chars = new char[run.length]; - segmentsText.getChars(run.start, run.start + run.length, chars, 0); - - final int maxGlyphs = (chars.length * 3 / 2) + 16; - int /*long*/ hHeap = OS.GetProcessHeap(); - run.glyphs = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, maxGlyphs * 2); - if (run.glyphs == 0) SWT.error(SWT.ERROR_NO_HANDLES); - run.clusters = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, maxGlyphs * 2); - if (run.clusters == 0) SWT.error(SWT.ERROR_NO_HANDLES); - run.visAttrs = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, maxGlyphs * SCRIPT_VISATTR_SIZEOF); - if (run.visAttrs == 0) SWT.error(SWT.ERROR_NO_HANDLES); - run.psc = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, OS.PTR_SIZEOF); - if (run.psc == 0) SWT.error(SWT.ERROR_NO_HANDLES); - final short script = run.analysis.eScript; - final SCRIPT_PROPERTIES sp = new SCRIPT_PROPERTIES(); - OS.MoveMemory(sp, device.scripts[script], SCRIPT_PROPERTIES.sizeof); - boolean shapeSucceed = shape(hdc, run, chars, buffer, maxGlyphs, sp); - if (!shapeSucceed) { - int /*long*/ hFont = OS.GetCurrentObject(hdc, OS.OBJ_FONT); - int /*long*/ newFont = 0; - /* - * Bug in Uniscribe. In some version of Uniscribe, ScriptStringAnalyse crashes - * when the character array is too long. The fix is to limit the size of character - * array to two. Note, limiting the array to only one character would cause surrogate - * pairs to stop working. - */ - char[] sampleChars = new char[Math.min(chars.length, 2)]; - SCRIPT_LOGATTR logAttr = new SCRIPT_LOGATTR(); - breakRun(run); - int count = 0; - for (int i = 0; i < chars.length; i++) { - OS.MoveMemory(logAttr, run.psla + (i * SCRIPT_LOGATTR.sizeof), SCRIPT_LOGATTR.sizeof); - if (!logAttr.fWhiteSpace) { - sampleChars[count++] = chars[i]; - if (count == sampleChars.length) break; - } - } - if (count > 0) { - int /*long*/ ssa = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, OS.SCRIPT_STRING_ANALYSIS_sizeof()); - int /*long*/ metaFileDc = OS.CreateEnhMetaFile(hdc, null, null, null); - int /*long*/ oldMetaFont = OS.SelectObject(metaFileDc, hFont); - int flags = OS.SSA_METAFILE | OS.SSA_FALLBACK | OS.SSA_GLYPHS | OS.SSA_LINK; - if (OS.ScriptStringAnalyse(metaFileDc, sampleChars, count, 0, -1, flags, 0, null, null, 0, 0, 0, ssa) == OS.S_OK) { - OS.ScriptStringOut(ssa, 0, 0, 0, null, 0, 0, false); - OS.ScriptStringFree(ssa); - } - OS.HeapFree(hHeap, 0, ssa); - OS.SelectObject(metaFileDc, oldMetaFont); - int /*long*/ metaFile = OS.CloseEnhMetaFile(metaFileDc); - final EMREXTCREATEFONTINDIRECTW emr = new EMREXTCREATEFONTINDIRECTW(); - class MetaFileEnumProc { - int /*long*/ metaFileEnumProc (int /*long*/ hDC, int /*long*/ table, int /*long*/ record, int /*long*/ nObj, int /*long*/ lpData) { - OS.MoveMemory(emr.emr, record, EMR.sizeof); - switch (emr.emr.iType) { - case OS.EMR_EXTCREATEFONTINDIRECTW: - OS.MoveMemory(emr, record, EMREXTCREATEFONTINDIRECTW.sizeof); - break; - case OS.EMR_EXTTEXTOUTW: - return 0; - } - return 1; - } - }; - MetaFileEnumProc object = new MetaFileEnumProc(); - /* Avoid compiler warnings */ - boolean compilerWarningWorkaround = false; - if (compilerWarningWorkaround) object.metaFileEnumProc(0, 0, 0, 0, 0); - Callback callback = new Callback(object, "metaFileEnumProc", 5); - int /*long*/ address = callback.getAddress(); - if (address == 0) SWT.error(SWT.ERROR_NO_MORE_CALLBACKS); - OS.EnumEnhMetaFile(0, metaFile, address, 0, null); - OS.DeleteEnhMetaFile(metaFile); - callback.dispose(); - newFont = OS.CreateFontIndirectW(emr.elfw.elfLogFont); - } else { - /* - * The run is composed only by white spaces, this happens when a run is split - * by a visual style. The font fallback for the script can not be determined - * using only white spaces. The solution is to use the font fallback of the - * previous or next run of the same script. - */ - int index = 0; - while (index < allRuns.length - 1) { - if (allRuns[index] == run) { - if (index > 0) { - StyleItem pRun = allRuns[index - 1]; - if (pRun.fallbackFont != 0 && pRun.analysis.eScript == run.analysis.eScript) { - LOGFONT logFont = OS.IsUnicode ? (LOGFONT)new LOGFONTW() : new LOGFONTA(); - OS.GetObject(pRun.fallbackFont, LOGFONT.sizeof, logFont); - newFont = OS.CreateFontIndirect(logFont); - } - } - if (newFont == 0) { - if (index + 1 < allRuns.length - 1) { - StyleItem nRun = allRuns[index + 1]; - if (nRun.analysis.eScript == run.analysis.eScript) { - shape(hdc, nRun); - if (nRun.fallbackFont != 0) { - LOGFONT logFont = OS.IsUnicode ? (LOGFONT)new LOGFONTW() : new LOGFONTA(); - OS.GetObject(nRun.fallbackFont, LOGFONT.sizeof, logFont); - newFont = OS.CreateFontIndirect(logFont); - } - } - } - } - break; - } - index++; - } - } - if (newFont != 0) { - OS.SelectObject(hdc, newFont); - if (shapeSucceed = shape(hdc, run, chars, buffer, maxGlyphs, sp)) { - run.fallbackFont = newFont; - } - } - if (!shapeSucceed) { - if (!sp.fComplex) { - run.analysis.fNoGlyphIndex = true; - if (shapeSucceed = shape(hdc, run, chars, buffer, maxGlyphs, sp)) { - run.fallbackFont = newFont; - } else { - run.analysis.fNoGlyphIndex = false; - } - } - } - if (!shapeSucceed) { - if (mLangFontLink2 != 0) { - int /*long*/[] hNewFont = new int /*long*/[1]; - int[] dwCodePages = new int[1], cchCodePages = new int[1]; - /* GetStrCodePages() */ - OS.VtblCall(4, mLangFontLink2, chars, chars.length, 0, dwCodePages, cchCodePages); - /* MapFont() */ - if (OS.VtblCall(10, mLangFontLink2, hdc, dwCodePages[0], chars[0], hNewFont) == OS.S_OK) { - LOGFONT logFont = OS.IsUnicode ? (LOGFONT)new LOGFONTW () : new LOGFONTA (); - OS.GetObject(hNewFont[0], LOGFONT.sizeof, logFont); - /* ReleaseFont() */ - OS.VtblCall(8, mLangFontLink2, hNewFont[0]); - int /*long*/ mLangFont = OS.CreateFontIndirect(logFont); - int /*long*/ oldFont = OS.SelectObject(hdc, mLangFont); - if (shapeSucceed = shape(hdc, run, chars, buffer, maxGlyphs, sp)) { - run.fallbackFont = mLangFont; - } else { - OS.SelectObject(hdc, oldFont); - OS.DeleteObject(mLangFont); - } - } - } - } - if (!shapeSucceed) OS.SelectObject(hdc, hFont); - if (newFont != 0 && newFont != run.fallbackFont) OS.DeleteObject(newFont); - } - - if (!shapeSucceed) { - /* - * Shape Failed. - * Give up and shape the run with the default font. - * Missing glyphs typically will be represent as black boxes in the text. - */ - OS.ScriptShape(hdc, run.psc, chars, chars.length, maxGlyphs, run.analysis, run.glyphs, run.clusters, run.visAttrs, buffer); - run.glyphCount = buffer[0]; - } - int[] abc = new int[3]; - run.advances = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, run.glyphCount * 4); - if (run.advances == 0) SWT.error(SWT.ERROR_NO_HANDLES); - run.goffsets = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, run.glyphCount * GOFFSET_SIZEOF); - if (run.goffsets == 0) SWT.error(SWT.ERROR_NO_HANDLES); - OS.ScriptPlace(hdc, run.psc, run.glyphs, run.glyphCount, run.visAttrs, run.analysis, run.advances, run.goffsets, abc); - run.width = abc[0] + abc[1] + abc[2]; - TextStyle style = run.style; - if (style != null) { - OUTLINETEXTMETRIC lotm = null; - if (style.underline || style.strikeout) { - lotm = OS.IsUnicode ? (OUTLINETEXTMETRIC)new OUTLINETEXTMETRICW() : new OUTLINETEXTMETRICA(); - if (OS.GetOutlineTextMetrics(hdc, OUTLINETEXTMETRIC.sizeof, lotm) == 0) { - lotm = null; - } - } - if (style.metrics != null) { - GlyphMetrics metrics = style.metrics; - /* - * Bug in Windows, on a Japanese machine, Uniscribe returns glyphcount - * equals zero for FFFC (possibly other unicode code points), the fix - * is to make sure the glyph is at least one pixel wide. - */ - run.width = metrics.width * Math.max (1, run.glyphCount); - run.ascent = metrics.ascent; - run.descent = metrics.descent; - run.leading = 0; - } else { - TEXTMETRIC lptm = null; - if (lotm != null) { - lptm = OS.IsUnicode ? (TEXTMETRIC)((OUTLINETEXTMETRICW)lotm).otmTextMetrics : ((OUTLINETEXTMETRICA)lotm).otmTextMetrics; - } else { - lptm = OS.IsUnicode ? (TEXTMETRIC)new TEXTMETRICW() : new TEXTMETRICA(); - OS.GetTextMetrics(hdc, lptm); - } - run.ascent = lptm.tmAscent; - run.descent = lptm.tmDescent; - run.leading = lptm.tmInternalLeading; - } - if (lotm != null) { - run.underlinePos = lotm.otmsUnderscorePosition; - run.underlineThickness = Math.max(1, lotm.otmsUnderscoreSize); - run.strikeoutPos = lotm.otmsStrikeoutPosition; - run.strikeoutThickness = Math.max(1, lotm.otmsStrikeoutSize); - } else { - run.underlinePos = 1; - run.underlineThickness = 1; - run.strikeoutPos = run.ascent / 2; - run.strikeoutThickness = 1; - } - run.ascent += style.rise; - run.descent -= style.rise; - } else { - TEXTMETRIC lptm = OS.IsUnicode ? (TEXTMETRIC)new TEXTMETRICW() : new TEXTMETRICA(); - OS.GetTextMetrics(hdc, lptm); - run.ascent = lptm.tmAscent; - run.descent = lptm.tmDescent; - run.leading = lptm.tmInternalLeading; - } -} - -int validadeOffset(int offset, int step) { - offset += step; - if (segments != null && segments.length > 2) { - for (int i = 0; i < segments.length; i++) { - if (translateOffset(segments[i]) - 1 == offset) { - offset += step; - break; - } - } - } - return offset; -} - -/** - * 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 {}"; -} - -int translateOffset(int offset) { - if (segments == null) return offset; - int nSegments = segments.length; - if (nSegments <= 1) return offset; - int length = text.length(); - if (length == 0) return offset; - if (nSegments == 2) { - if (segments[0] == 0 && segments[1] == length) return offset; - } - for (int i = 0; i < nSegments && offset - i >= segments[i]; i++) { - offset++; - } - return offset; -} - -int untranslateOffset(int offset) { - if (segments == null) return offset; - int nSegments = segments.length; - if (nSegments <= 1) return offset; - int length = text.length(); - if (length == 0) return offset; - if (nSegments == 2) { - if (segments[0] == 0 && segments[1] == length) return offset; - } - for (int i = 0; i < nSegments && offset > segments[i]; i++) { - offset--; - } - return offset; -} -} diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Transform.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Transform.java deleted file mode 100644 index c4236ad294..0000000000 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Transform.java +++ /dev/null @@ -1,369 +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.gdip.*; - -/** - * 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 int /*long*/ 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); - this.device.checkGDIP(); - handle = Gdip.Matrix_new(m11, m12, m21, m22, dx, dy); - if (handle == 0) 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() { - Gdip.Matrix_delete(handle); - handle = 0; -} - -/** - * 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); - Gdip.Matrix_GetElements(handle, elements); -} - -/** - * 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); - Gdip.Matrix_SetElements(handle, 1, 0, 0, 1, 0, 0); -} - -/** - * 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 (Gdip.Matrix_Invert(handle) != 0) SWT.error(SWT.ERROR_CANNOT_INVERT_MATRIX); -} - -/** - * 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 == 0; -} - -/** - * 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 Gdip.Matrix_IsIdentity(handle); -} - -/** - * 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); - Gdip.Matrix_Multiply(handle, matrix.handle, Gdip.MatrixOrderPrepend); -} - -/** - * 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); - Gdip.Matrix_Rotate(handle, angle, Gdip.MatrixOrderPrepend); -} - -/** - * 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); - Gdip.Matrix_Scale(handle, scaleX, scaleY, Gdip.MatrixOrderPrepend); -} - -/** - * 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); - Gdip.Matrix_SetElements(handle, m11, m12, m21, m22, dx, dy); -} - -/** - * 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); - Gdip.Matrix_Shear(handle, shearX, shearY, Gdip.MatrixOrderPrepend); -} - -/** - * 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); - Gdip.Matrix_TransformPoints(handle, pointArray, pointArray.length / 2); -} - -/** - * 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); - Gdip.Matrix_Translate(handle, offsetX, offsetY, Gdip.MatrixOrderPrepend); -} - -/** - * 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] + "}"; -} - -} |