summaryrefslogtreecommitdiffstats
path: root/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics')
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Color.java325
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Cursor.java460
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Device.java972
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/DeviceData.java23
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Font.java258
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/FontData.java669
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/FontMetrics.java183
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java4979
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GCData.java64
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java2129
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Path.java602
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Pattern.java250
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Region.java597
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java3328
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Transform.java369
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] + "}";
-}
-
-}