# HG changeset patch
# User Frank Benoit
+ * Application code must explicitly invoke the
+ * IMPORTANT: This field is not part of the DWT
+ * public API. It is marked public only so that it can be shared
+ * within the packages provided by DWT. It is not available on all
+ * platforms and should never be accessed from application code.
+ *
+ * You must dispose the color when it is no longer required.
+ *
+ * You must dispose the color when it is no longer required.
+ *
+ * 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
+ * IMPORTANT: This method is not part of the public
+ * API for
* IMPORTANT: This field is not part of the DWT
@@ -64,7 +67,7 @@
*/
public int hPalette = 0;
int [] colorRefCount;
-
+
/* System Font */
int systemFont;
@@ -81,7 +84,7 @@
int [] gdipToken;
bool disposed;
-
+
final static Object CREATE_LOCK = new Object();
/*
@@ -102,14 +105,14 @@
try {
Class.forName ("org.eclipse.swt.widgets.Display"); //$NON-NLS-1$
} catch (Throwable e) {}
- }
+ }
/*
* TEMPORARY CODE.
*/
static synchronized Device getDevice () {
if (DeviceFinder !is null) DeviceFinder.run();
- Device device = CurrentDevice;
+ Device device = CurrentDevice;
CurrentDevice = null;
return device;
}
@@ -117,12 +120,12 @@
/**
* Constructs a new instance of this class.
*
- * You must dispose the device when it is no longer required.
+ * You must dispose the device when it is no longer required.
*
- * You must dispose the device when it is no longer required.
+ * You must dispose the device when it is no longer required.
* RGB
.
+ * Color.dispose()
+ * method to release the operating system resources managed by each instance
+ * when those instances are no longer required.
+ *
+ *
+ *
+ * @see #dispose
+ */
+public this (Device device, int red, int green, int blue) {
+ if (device is null) device = Device.getDevice();
+ if (device is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
+ init(device, red, green, blue);
+ if (device.tracking) device.new_Object(this);
+}
+
+/**
+ * Constructs a new instance of this class given a device and an
+ * RGB
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.
+ *
+ *
+ *
+ * @see #dispose
+ */
+public this (Device device, RGB rgb) {
+ if (device is null) device = Device.getDevice();
+ if (device is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
+ if (rgb is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
+ init(device, rgb.red, rgb.green, rgb.blue);
+ if (device.tracking) device.new_Object(this);
+}
+
+/**
+ * Disposes of the operating system resources associated with
+ * the color. Applications must dispose of all colors which
+ * they allocate.
+ */
+public void dispose() {
+ if (handle is -1) return;
+ if (device.isDisposed()) return;
+
+ /*
+ * 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.
+ */
+ auto hPal = device.hPalette;
+ if (hPal !is null) {
+ int index = OS.GetNearestPaletteIndex(hPal, handle);
+ int[] colorRefCount = device.colorRefCount;
+ if (colorRefCount[index] > 0) {
+ colorRefCount[index]--;
+ }
+ }
+ handle = -1;
+ if (device.tracking) device.dispose_Object(this);
+ device = null;
+}
+
+/**
+ * Compares the argument to the receiver, and returns true
+ * if they represent the same object using a class
+ * specific comparison.
+ *
+ * @param object the object to compare with this object
+ * @return true
if the object is the same as this object and false
otherwise
+ *
+ * @see #hashCode
+ */
+public bool equals (Object object) {
+ if (object is this) return true;
+ if (!(cast(Color)object)) return false;
+ Color color = cast(Color) object;
+ return device is color.device && (handle & 0xFFFFFF) is (color.handle & 0xFFFFFF);
+}
+
+/**
+ * Returns the amount of blue in the color, from 0 to 255.
+ *
+ * @return the blue component of the color
+ *
+ * @exception DWTException
+ *
+ */
+public int getBlue () {
+ if (isDisposed()) DWT.error(DWT.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 DWTException
+ *
+ */
+public int getGreen () {
+ if (isDisposed()) DWT.error(DWT.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 DWTException
+ *
+ */
+public int getRed () {
+ if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
+ return handle & 0xFF;
+}
+
+/**
+ * Returns an RGB
representing the receiver.
+ *
+ * @return the RGB for the color
+ *
+ * @exception DWTException
+ *
+ */
+public RGB getRGB () {
+ if (isDisposed()) DWT.error(DWT.ERROR_GRAPHIC_DISPOSED);
+ return new RGB(cast(int)handle & 0xFF,cast(int) (handle & 0xFF00) >> 8,cast(int) (handle & 0xFF0000) >> 16);
+}
+
+/**
+ * Returns an integer hash code for the receiver. Any two
+ * objects that return true
when passed to
+ * equals
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
+ *
+ *
+ * @see #dispose
+ */
+void init(Device device, int red, int green, int blue) {
+ if (red > 255 || red < 0 || green > 255 || green < 0 || blue > 255 || blue < 0) {
+ DWT.error(DWT.ERROR_INVALID_ARGUMENT);
+ }
+ this.device = device;
+ handle = (red & 0xFF) | ((green & 0xFF) << 8) | ((blue & 0xFF) << 16);
+
+ /* If this is not a palette-based device, return */
+ auto hPal = device.hPalette;
+ if (hPal is null) 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 */
+ PALETTEENTRY entry;
+ OS.GetPaletteEntries(hPal, index, 1, &entry);
+ if ((entry.peRed is cast(byte)red) && (entry.peGreen is cast(byte)green) &&
+ (entry.peBlue is cast(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] is 0) {
+ index = i;
+ break;
+ }
+ i++;
+ }
+ if (i is colorRefCount.length) {
+ /* No free entries, use the closest one */
+ /* Remake the handle from the actual rgbs */
+ handle = (entry.peRed & 0xFF) | ((entry.peGreen & 0xFF) << 8) |
+ ((entry.peBlue & 0xFF) << 16);
+ } else {
+ /* Found a free entry */
+ entry.peRed = cast(BYTE)(red & 0xFF);
+ entry.peGreen = cast(BYTE)(green & 0xFF);
+ entry.peBlue = cast(BYTE)(blue & 0xFF);
+ entry.peFlags = 0;
+ OS.SetPaletteEntries(hPal, index, 1, &entry);
+ }
+ colorRefCount[index]++;
+}
+
+/**
+ * Returns true
if the color has been disposed,
+ * and false
otherwise.
+ * true
when the color is disposed and false
otherwise
+ */
+public bool isDisposed() {
+ return handle is -1;
+}
+
+/**
+ * Returns a string containing a concise, human-readable
+ * description of the receiver.
+ *
+ * @return a string representation of the receiver
+ */
+public char[] toString () {
+ if (isDisposed()) return "Color {*DISPOSED*}"; //$NON-NLS-1$
+ return Format( "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.
+ * Color
. It is marked public only so that it
+ * can be shared within the packages provided by DWT. It is not
+ * available on all platforms, and should never be called from
+ * application code.
+ *
@@ -407,7 +410,7 @@
/**
* 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
+ * 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
@@ -460,12 +463,12 @@
*/
public FontData [] getFontList (String faceName, bool scalable) {
checkDevice ();
-
+
/* Create the callback */
Callback callback = new Callback (this, "EnumFontFamProc", 4); //$NON-NLS-1$
int lpEnumFontFamProc = callback.getAddress ();
if (lpEnumFontFamProc is 0) DWT.error (DWT.ERROR_NO_MORE_CALLBACKS);
-
+
/* Initialize the instance variables */
metrics = OS.IsUnicode ? (TEXTMETRIC)new TEXTMETRICW() : new TEXTMETRICA();
pixels = new int[nFonts];
@@ -478,10 +481,10 @@
/* Enumerate */
int offset = 0;
int hDC = internal_new_GC (null);
- if (faceName is null) {
+ if (faceName is 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
@@ -530,7 +533,7 @@
System.arraycopy (result, 0, newResult, 0, count);
result = newResult;
}
-
+
/* Clean up */
callback.dispose ();
logFonts = null;
@@ -651,7 +654,7 @@
* If subclasses reimplement this method, they must
* call the
super
implementation.
*
* IMPORTANT: This method is not part of the public @@ -741,12 +744,12 @@ * application code. *
* - * @param data the platform specific GC data + * @param data the platform specific GC data * @return the platform specific GC handle */ public abstract int internal_new_GC (GCData data); -/** +/** * Invokes platform specific functionality to dispose a GC handle. ** IMPORTANT: This method is not part of the public @@ -757,7 +760,7 @@ *
* * @param hDC the platform specific GC handle - * @param data the platform specific GC data + * @param data the platform specific GC data */ public abstract void internal_dispose_GC (int hDC, GCData data); @@ -788,7 +791,7 @@ * * * @see Font - * + * * @since 3.3 */ public bool loadFont (String path) {