Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics')
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Color.java257
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Cursor.java291
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/DefaultGtkStyle.java116
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Device.java482
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/DeviceData.java24
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Font.java209
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/FontData.java546
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/FontMetrics.java122
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java1697
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GCData.java28
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java638
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Pixbuffer.java492
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Region.java263
13 files changed, 5165 insertions, 0 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Color.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Color.java
new file mode 100644
index 0000000000..e796d2151c
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Color.java
@@ -0,0 +1,257 @@
+package org.eclipse.swt.graphics;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.internal.gtk.*;
+
+/**
+ * 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
+ */
+public final class Color {
+ /**
+ * the handle to the OS color resource
+ * (Warning: This field is platform dependent)
+ */
+ public GdkColor handle;
+ Device display;
+Color() {
+}
+/**
+ * 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_INVALID_ARGUMENT - if the red, green or blue argument is not between 0 and 255</li>
+ * </ul>
+ *
+ * @see #dispose
+ */
+public Color(Device display, int red, int green, int blue) {
+ init(display, red, green, blue);
+}
+/**
+ * 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_INVALID_ARGUMENT - if the red, green or blue components of the argument are not between 0 and 255</li>
+ * <li>ERROR_NULL_ARGUMENT - if the rgb argument is null</li>
+ * </ul>
+ *
+ * @see #dispose
+ */
+public Color(Device display, RGB rgb) {
+ if (rgb == null) error(SWT.ERROR_NULL_ARGUMENT);
+ init(display, rgb.red, rgb.green, rgb.blue);
+}
+/**
+ * Disposes of the operating system resources associated with
+ * the color. Applications must dispose of all colors which
+ * they allocate.
+ */
+public void dispose() {
+ /**
+ * If this is a palette-based display,
+ * Decrease the reference count for this color.
+ * If the reference count reaches 0, the slot may
+ * be reused when another color is allocated.
+ */
+ if (display.colorRefCount != null) {
+ if (--display.colorRefCount[handle.pixel] == 0) {
+ display.gdkColors[handle.pixel] = null;
+ }
+ }
+ int colormap = OS.gdk_colormap_get_system();
+ OS.gdk_colors_free(colormap, new int[] { handle.pixel }, 1, 0);
+ this.display = null;
+ this.handle = null;
+}
+/**
+ * Compares the argument to the receiver, and returns true
+ * if they represent the <em>same</em> object using a class
+ * specific comparison.
+ *
+ * @param object the object to compare with this object
+ * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise
+ *
+ * @see #hashCode
+ */
+public boolean equals(Object object) {
+ if (object == this) return true;
+ if (!(object instanceof Color)) return false;
+ Color color = (Color)object;
+ GdkColor xColor = color.handle;
+ return (handle.pixel == xColor.pixel)&&(handle.red == xColor.red) && (handle.green == xColor.green) && (handle.blue == xColor.blue) && (this.display == color.display);
+}
+void error(int code) {
+ throw new SWTError(code);
+}
+/**
+ * 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() {
+ return (handle.blue >> 8) & 0xFF;
+}
+/**
+ * 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() {
+ return (handle.green >> 8) & 0xFF;
+}
+/**
+ * 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() {
+ return (handle.red >> 8) & 0xFF;
+}
+
+/**
+ * Returns an integer hash code for the receiver. Any two
+ * objects which 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.red ^ handle.green ^ handle.blue;
+}
+/**
+ * Returns an <code>RGB</code> representing the receiver.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public RGB getRGB () {
+ return new RGB(getRed(), getGreen(), getBlue());
+}
+
+void init(Device display, int red, int green, int blue) {
+ if (display == null) display = Display.getDefault();
+ this.display = display;
+ handle = new GdkColor();
+ handle.red = (short)((red & 0xFF) | ((red & 0xFF) << 8));
+ handle.green = (short)((green & 0xFF) | ((green & 0xFF) << 8));
+ handle.blue = (short)((blue & 0xFF) | ((blue & 0xFF) << 8));
+ int colormap = OS.gdk_colormap_get_system();
+ OS.gdk_color_alloc(colormap, handle);
+ if (display.colorRefCount != null) {
+ // Make a copy of the color to put in the colors array
+ GdkColor colorCopy = new GdkColor();
+ colorCopy.red = handle.red;
+ colorCopy.green = handle.green;
+ colorCopy.blue = handle.blue;
+ colorCopy.pixel = handle.pixel;
+ display.gdkColors[colorCopy.pixel] = colorCopy;
+ display.colorRefCount[colorCopy.pixel]++;
+ }
+}
+/**
+ * Returns <code>true</code> if the color has been disposed,
+ * and <code>false</code> otherwise.
+ * <p>
+ * This method gets the dispose state for the color.
+ * When a color has been disposed, it is an error to
+ * invoke any other method using the color.
+ *
+ * @return <code>true</code> when the color is disposed and <code>false</code> otherwise
+ */
+public boolean isDisposed() {
+ return handle == null;
+}
+/**
+ * Returns a string containing a concise, human-readable
+ * description of the receiver.
+ *
+ * @return a string representation of the receiver
+ */
+public String toString () {
+ return "Color {" + getRed() + ", " + getGreen() + ", " + getBlue() + "}";
+}
+
+public static Color gtk_new(GdkColor gdkColor) {
+ Color color = new Color(null, gtk_getRGBIntensities(gdkColor));
+ return color;
+}
+
+static RGB gtk_getRGBIntensities(GdkColor gdkColor) {
+ boolean intensitiesAreZero = (gdkColor.red==0) && (gdkColor.green==0) && (gdkColor.blue==0);
+ if (!intensitiesAreZero) return new RGB ((gdkColor.red&0xFF00)>>8,
+ (gdkColor.green&0xFF00)>>8,
+ (gdkColor.blue&0xFF00)>>8 );
+ GdkVisual visual = new GdkVisual();
+ OS.memmove(visual, OS.gdk_visual_get_system(), GdkVisual.sizeof);
+
+ int r = (gdkColor.pixel&visual.red_mask) >> visual.red_shift;
+ if (visual.red_prec<8) r = r << (8 - visual.red_prec);
+ else r = r >> (visual.red_prec - 8);
+ int g = (gdkColor.pixel&visual.green_mask) >> visual.green_shift;
+ if (visual.green_prec<8) g = g << (8 - visual.green_prec);
+ else g = g >> (visual.green_prec - 8);
+ int b = (gdkColor.pixel&visual.blue_mask) >> visual.blue_shift;
+ if (visual.blue_prec<8) b = b << (8 - visual.blue_prec);
+ else b = b >> (visual.blue_prec - 8);
+
+ return new RGB(r, g, b);
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Cursor.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Cursor.java
new file mode 100644
index 0000000000..216957b584
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Cursor.java
@@ -0,0 +1,291 @@
+package org.eclipse.swt.graphics;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.internal.gtk.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.internal.image.*;
+
+/**
+ * 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>
+ */
+public final class Cursor {
+ /**
+ * the handle to the OS cursor resource
+ * (Warning: This field is platform dependent)
+ */
+ public int handle;
+Cursor () {
+}
+/**
+ * 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_INVALID_ARGUMENT - when an unknown style is specified</li>
+ * </ul>
+ *
+ * @see Cursor for the supported style values
+ */
+public Cursor(Device display, int style) {
+ int osFlag = 0;
+ switch (style) {
+ case SWT.CURSOR_ARROW:
+ osFlag = OS.GDK_LEFT_PTR;
+ break;
+ case SWT.CURSOR_WAIT:
+ osFlag = OS.GDK_WATCH;
+ break;
+ case SWT.CURSOR_CROSS:
+ osFlag = OS.GDK_CROSS;
+ break;
+ case SWT.CURSOR_APPSTARTING:
+ osFlag = OS.GDK_WATCH;
+ break;
+ case SWT.CURSOR_HAND:
+ osFlag = OS.GDK_HAND1;
+ break;
+ case SWT.CURSOR_HELP:
+ osFlag = OS.GDK_QUESTION_ARROW;
+ break;
+ case SWT.CURSOR_SIZEALL:
+ osFlag = OS.GDK_DIAMOND_CROSS;
+ break;
+ case SWT.CURSOR_SIZENESW:
+ osFlag = OS.GDK_SIZING;
+ break;
+ case SWT.CURSOR_SIZENS:
+ osFlag = OS.GDK_DOUBLE_ARROW;
+ break;
+ case SWT.CURSOR_SIZENWSE:
+ osFlag = OS.GDK_SIZING;
+ break;
+ case SWT.CURSOR_SIZEWE:
+ osFlag = OS.GDK_SB_H_DOUBLE_ARROW;
+ break;
+ case SWT.CURSOR_SIZEN:
+ osFlag = OS.GDK_TOP_SIDE;
+ break;
+ case SWT.CURSOR_SIZES:
+ osFlag = OS.GDK_BOTTOM_SIDE;
+ break;
+ case SWT.CURSOR_SIZEE:
+ osFlag = OS.GDK_RIGHT_SIDE;
+ break;
+ case SWT.CURSOR_SIZEW:
+ osFlag = OS.GDK_LEFT_SIDE;
+ break;
+ case SWT.CURSOR_SIZENE:
+ osFlag = OS.GDK_TOP_RIGHT_CORNER;
+ break;
+ case SWT.CURSOR_SIZESE:
+ osFlag = OS.GDK_BOTTOM_RIGHT_CORNER;
+ break;
+ case SWT.CURSOR_SIZESW:
+ osFlag = OS.GDK_BOTTOM_LEFT_CORNER;
+ break;
+ case SWT.CURSOR_SIZENW:
+ osFlag = OS.GDK_TOP_LEFT_CORNER;
+ break;
+ case SWT.CURSOR_UPARROW:
+ osFlag = OS.GDK_SB_UP_ARROW;
+ break;
+ case SWT.CURSOR_IBEAM:
+ osFlag = OS.GDK_XTERM;
+ break;
+ case SWT.CURSOR_NO:
+ osFlag = OS.GDK_X_CURSOR;
+ break;
+ default:
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ this.handle = OS.gdk_cursor_new(osFlag);
+}
+/**
+ * Constructs a new cursor given a device, image and mask
+ * data describing the desired cursor appearance, and the x
+ * and y co-ordinates 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 - when a null argument is passed that is not allowed</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the source and the mask are not the same
+ * size, or either is not of depth one, or if the hotspot is outside
+ * the bounds of the image</li>
+ * </ul>
+ * @exception SWTError <ul>
+ * <li>ERROR_NO_HANDLES - if an error occurred constructing the cursor</li>
+ * </ul>
+ */
+public Cursor(Device display, ImageData source, ImageData mask, int hotspotX, int hotspotY) {
+ if (source == null) error(SWT.ERROR_NULL_ARGUMENT);
+ if (mask == null) {
+ if (!(source.getTransparencyType() == SWT.TRANSPARENCY_MASK)) 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) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ /* Check depths */
+ if (mask.depth != 1) error(SWT.ERROR_INVALID_ARGUMENT);
+ if (source.depth != 1) error(SWT.ERROR_INVALID_ARGUMENT);
+ /* Check the hotspots */
+ if (hotspotX >= source.width || hotspotX < 0 ||
+ hotspotY >= source.height || hotspotY < 0) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+
+ /* Swap the bits if necessary */
+ byte[] sourceData = new byte[source.data.length];
+ byte[] maskData = new byte[mask.data.length];
+ /* Swap the bits in each byte */
+ byte[] data = source.data;
+ for (int i = 0; i < data.length; i++) {
+ byte s = data[i];
+ sourceData[i] = (byte)(((s & 0x80) >> 7) |
+ ((s & 0x40) >> 5) |
+ ((s & 0x20) >> 3) |
+ ((s & 0x10) >> 1) |
+ ((s & 0x08) << 1) |
+ ((s & 0x04) << 3) |
+ ((s & 0x02) << 5) |
+ ((s & 0x01) << 7));
+ sourceData[i] = (byte) ~sourceData[i];
+ }
+ data = mask.data;
+ for (int i = 0; i < data.length; i++) {
+ byte s = data[i];
+ maskData[i] = (byte)(((s & 0x80) >> 7) |
+ ((s & 0x40) >> 5) |
+ ((s & 0x20) >> 3) |
+ ((s & 0x10) >> 1) |
+ ((s & 0x08) << 1) |
+ ((s & 0x04) << 3) |
+ ((s & 0x02) << 5) |
+ ((s & 0x01) << 7));
+ maskData[i] = (byte) ~maskData[i];
+ }
+
+ int sourcePixmap = OS.gdk_bitmap_create_from_data(0, sourceData, source.width, source.height);
+ if (sourcePixmap==0) SWT.error(SWT.ERROR_NO_HANDLES);
+ int maskPixmap = OS.gdk_bitmap_create_from_data(0, maskData, source.width, source.height);
+ if (maskPixmap==0) SWT.error(SWT.ERROR_NO_HANDLES);
+
+ /* Get the colors */
+ GdkColor foreground = new GdkColor();
+ foreground.red = 0;
+ foreground.green = 0;
+ foreground.blue = 0;
+ GdkColor background = new GdkColor();
+ background.red = (short)65535;
+ background.green = (short)65535;
+ background.blue = (short)65535;
+
+ /* Create the cursor */
+ /* For some reason, mask and source take reverse roles, both here and on Motif */
+ handle = OS.gdk_cursor_new_from_pixmap (maskPixmap, sourcePixmap, foreground, background, hotspotX, hotspotY);
+ /* Dispose the pixmaps */
+ OS.gdk_pixmap_unref (sourcePixmap);
+ OS.gdk_pixmap_unref (maskPixmap);
+ if (handle == 0) error(SWT.ERROR_NO_HANDLES);
+}
+/**
+ * Disposes of the operating system resources associated with
+ * the cursor. Applications must dispose of all cursors which
+ * they allocate.
+ */
+public void dispose() {
+ if (handle != 0) OS.gdk_cursor_destroy(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) {
+ return (object == this) || ((object instanceof Cursor) && (handle == ((Cursor)object).handle));
+}
+void error(int code) {
+ throw new SWTError(code);
+}
+public static Cursor gtk_new(int handle) {
+ Cursor cursor = new Cursor();
+ cursor.handle = handle;
+ return cursor;
+}
+/**
+ * Returns an integer hash code for the receiver. Any two
+ * objects which return <code>true</code> when passed to
+ * <code>equals</code> must return the same value for this
+ * method.
+ *
+ * @return the receiver's hash
+ *
+ * @see #equals
+ */
+public int hashCode() {
+ return handle;
+}
+/**
+ * Returns <code>true</code> if the cursor has been disposed,
+ * and <code>false</code> otherwise.
+ * <p>
+ * This method gets the dispose state for the cursor.
+ * When a cursor has been disposed, it is an error to
+ * invoke any other method using the cursor.
+ *
+ * @return <code>true</code> when the cursor is disposed and <code>false</code> otherwise
+ */
+public boolean isDisposed() {
+ return handle == 0;
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/DefaultGtkStyle.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/DefaultGtkStyle.java
new file mode 100644
index 0000000000..952fa9d404
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/DefaultGtkStyle.java
@@ -0,0 +1,116 @@
+package org.eclipse.swt.graphics;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.internal.gtk.*;
+
+class DefaultGtkStyle {
+
+ private static DefaultGtkStyle instance = null;
+ private GtkStyle style = null;
+ private int defaultFont;
+
+ public Color foregroundColorNORMAL() {
+ return new Color(null,
+ ((short)0xFF00 & style.fg0_red)>>8,
+ ((short)0xFF00 & style.fg0_green)>>8,
+ ((short)0xFF00 & style.fg0_blue)>>8);
+ }
+
+ public Color backgroundColorNORMAL() {
+ return new Color(null,
+ ((short)0xFF00 & style.bg0_red)>>8,
+ ((short)0xFF00 & style.bg0_green)>>8,
+ ((short)0xFF00 & style.bg0_blue)>>8);
+ }
+
+ public Color foregroundColorACTIVE() {
+ return new Color(null,
+ ((short)0xFF00 & style.fg1_red)>>8,
+ ((short)0xFF00 & style.fg1_green)>>8,
+ ((short)0xFF00 & style.fg1_blue)>>8);
+ }
+
+ public Color backgroundColorACTIVE() {
+ return new Color(null,
+ ((short)0xFF00 & style.bg1_red)>>8,
+ ((short)0xFF00 & style.bg1_green)>>8,
+ ((short)0xFF00 & style.bg1_blue)>>8);
+ }
+
+ public Color foregroundColorPRELIGHT() {
+ return new Color(null,
+ ((short)0xFF00 & style.fg2_red)>>8,
+ ((short)0xFF00 & style.fg2_green)>>8,
+ ((short)0xFF00 & style.fg2_blue)>>8);
+ }
+
+ public Color backgroundColorPRELIGHT() {
+ return new Color(null,
+ ((short)0xFF00 & style.bg2_red)>>8,
+ ((short)0xFF00 & style.bg2_green)>>8,
+ ((short)0xFF00 & style.bg2_blue)>>8);
+ }
+
+ public Color foregroundColorSELECTED() {
+ return new Color(null,
+ ((short)0xFF00 & style.fg3_red)>>8,
+ ((short)0xFF00 & style.fg3_green)>>8,
+ ((short)0xFF00 & style.fg3_blue)>>8);
+ }
+
+ public Color backgroundColorSELECTED() {
+ return new Color(null,
+ ((short)0xFF00 & style.bg3_red)>>8,
+ ((short)0xFF00 & style.bg3_green)>>8,
+ ((short)0xFF00 & style.bg3_blue)>>8);
+ }
+
+ public Color foregroundColorINSENSITIVE() {
+ return new Color(null,
+ ((short)0xFF00 & style.fg4_red)>>8,
+ ((short)0xFF00 & style.fg4_green)>>8,
+ ((short)0xFF00 & style.fg4_blue)>>8);
+ }
+
+ public Color backgroundColorINSENSITIVE() {
+ return new Color(null,
+ ((short)0xFF00 & style.bg4_red)>>8,
+ ((short)0xFF00 & style.bg4_green)>>8,
+ ((short)0xFF00 & style.bg4_blue)>>8);
+ }
+
+ public int loadDefaultFont() {
+ if (defaultFont == 0) {
+ int fnames = Font.getFontNameList(style.font);
+ int slength = OS.g_slist_length(fnames);
+ if (slength < 1) SWT.error(SWT.ERROR_UNSPECIFIED);
+ int name1 = OS.g_slist_nth_data(fnames, 0);
+ int length = OS.strlen(name1);
+ byte [] buffer1 = new byte[length];
+ OS.memmove(buffer1, name1, length);
+ defaultFont = OS.gdk_font_load(buffer1);
+ if (defaultFont==0) SWT.error(SWT.ERROR_UNSPECIFIED);
+ GdkFont gdkFont = new GdkFont();
+ OS.memmove(gdkFont, defaultFont, GdkFont.sizeof);
+ if (gdkFont.type != OS.GDK_FONT_FONT) SWT.error(SWT.ERROR_UNSPECIFIED);
+ }
+ return defaultFont;
+ }
+
+ public static DefaultGtkStyle instance() {
+ if (instance==null) instance = new DefaultGtkStyle();
+ return instance;
+ }
+
+ private DefaultGtkStyle() {
+ style = new GtkStyle();
+ OS.memmove(style, OS.gtk_widget_get_default_style(), GtkStyle.sizeof);
+ }
+
+}
+
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Device.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Device.java
new file mode 100644
index 0000000000..f98cf11f6a
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Device.java
@@ -0,0 +1,482 @@
+package org.eclipse.swt.graphics;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.internal.*;
+import org.eclipse.swt.internal.gtk.*;
+
+public abstract class Device implements Drawable {
+
+ /* Debugging */
+ public static boolean DEBUG;
+ boolean debug = DEBUG;
+ boolean tracking = DEBUG;
+ Error [] errors;
+ Object [] objects;
+
+ /* Colormap and reference count */
+ GdkColor [] gdkColors;
+ int [] colorRefCount;
+
+ /* Disposed flag */
+ boolean disposed;
+
+ /*
+ * The following colors are listed in the Windows
+ * Programmer's Reference as the colors in the default
+ * palette.
+ */
+ Color COLOR_BLACK, COLOR_DARK_RED, COLOR_DARK_GREEN, COLOR_DARK_YELLOW, COLOR_DARK_BLUE;
+ Color COLOR_DARK_MAGENTA, COLOR_DARK_CYAN, COLOR_GRAY, COLOR_DARK_GRAY, COLOR_RED;
+ Color COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE;
+
+ /*
+ * 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.
+ *
+ * This code will be removed in the future.
+ */
+ protected static Device CurrentDevice;
+ protected static Runnable DeviceFinder;
+ static {
+ try {
+ Class.forName ("org.eclipse.swt.widgets.Display");
+ } catch (Throwable e) {}
+ }
+
+/*
+* TEMPORARY CODE.
+*/
+static 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>
+ *
+ * @param data the DeviceData which describes the receiver
+ *
+ * @see #create
+ * @see #init
+ * @see DeviceData
+ */
+public Device(DeviceData data) {
+ if (data != null) {
+ debug = data.debug;
+ tracking = data.tracking;
+ }
+ create (data);
+ init ();
+ if (tracking) {
+ errors = new Error [128];
+ objects = new Object [128];
+ }
+}
+
+protected void checkDevice () {
+ if (disposed) SWT.error(SWT.ERROR_DEVICE_DISPOSED);
+}
+
+protected void create (DeviceData data) {
+}
+
+/**
+ * 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 () {
+ if (isDisposed()) return;
+ checkDevice ();
+ release ();
+ destroy ();
+ disposed = true;
+ if (tracking) {
+ objects = null;
+ errors = null;
+ }
+}
+
+void dispose_Object (Object object) {
+ for (int i=0; i<objects.length; i++) {
+ if (objects [i] == object) {
+ objects [i] = null;
+ errors [i] = null;
+ return;
+ }
+ }
+}
+
+protected void destroy () {
+}
+
+/**
+ * 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 ();
+ SWT.error (SWT.ERROR_NOT_IMPLEMENTED);
+ return new Rectangle(0, 0, 0, 0);
+}
+
+/**
+ * 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;
+ int count = 0, length = 0;
+ if (tracking) 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++;
+ }
+ }
+ return data;
+}
+
+/**
+ * Returns a rectangle which describes the area of the
+ * receiver which is capable of displaying data.
+ *
+ * @return the client area
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see #getBounds
+ */
+public Rectangle getClientArea () {
+ checkDevice ();
+ 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 ();
+ SWT.error (SWT.ERROR_NOT_IMPLEMENTED);
+ return 0;
+}
+
+/**
+ * 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 ();
+ SWT.error (SWT.ERROR_NOT_IMPLEMENTED);
+ return new Point (72, 72);
+}
+
+/**
+ * Returns <code>FontData</code> objects which describe
+ * the fonts which 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 true if scalable fonts should be 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 ();
+ String xlfd;
+ if (faceName == null) {
+ xlfd = "-*";
+ } else {
+ int dashIndex = faceName.indexOf('-');
+ if (dashIndex < 0) {
+ xlfd = "-*-" + faceName + "-*";
+ } else {
+ xlfd = "-" + faceName + "-*";
+ }
+ }
+ /* Use the character encoding for the default locale */
+ byte [] buffer1 = Converter.wcsToMbcs (null, xlfd, true);
+ int [] ret = new int [1];
+ int listPtr = OS.XListFonts (buffer1, 65535, ret);
+ int ptr = listPtr;
+ int [] intBuf = new int [1];
+ FontData [] fd = new FontData [ret [0]];
+ int fdIndex = 0;
+ for (int i = 0; i < ret [0]; i++) {
+ OS.memmove (intBuf, ptr, 4);
+ int charPtr = intBuf [0];
+ int length = OS.strlen (charPtr);
+ byte [] buffer2 = new byte [length];
+ OS.memmove (buffer2, charPtr, length);
+ /* Use the character encoding for the default locale */
+ char [] chars = Converter.mbcsToWcs (null, buffer2);
+ FontData data = FontData.gtk_new (new String (chars));
+ boolean isScalable = data.averageWidth == 0 && data.pixels == 0 && data.points == 0;
+ if (isScalable == scalable) {
+ fd [fdIndex++] = data;
+ }
+ ptr += 4;
+ }
+ // FIXME, leaking font list
+// OS.XFreeFontNames (listPtr);
+ if (fdIndex == ret [0]) return fd;
+ FontData [] result = new FontData [fdIndex];
+ System.arraycopy (fd, 0, result, 0, fdIndex);
+ return result;
+}
+
+/**
+ * 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 free'd because it was allocated by the system,
+ * not the application.
+ *
+ * @param id the color constant
+ * @return the matching color
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see SWT
+ */
+public Color getSystemColor (int id) {
+ checkDevice ();
+ switch (id) {
+ case SWT.COLOR_BLACK: return COLOR_BLACK;
+ case SWT.COLOR_DARK_RED: return COLOR_DARK_RED;
+ case SWT.COLOR_DARK_GREEN: return COLOR_DARK_GREEN;
+ case SWT.COLOR_DARK_YELLOW: return COLOR_DARK_YELLOW;
+ case SWT.COLOR_DARK_BLUE: return COLOR_DARK_BLUE;
+ case SWT.COLOR_DARK_MAGENTA: return COLOR_DARK_MAGENTA;
+ case SWT.COLOR_DARK_CYAN: return COLOR_DARK_CYAN;
+ case SWT.COLOR_GRAY: return COLOR_GRAY;
+ case SWT.COLOR_DARK_GRAY: return COLOR_DARK_GRAY;
+ case SWT.COLOR_RED: return COLOR_RED;
+ case SWT.COLOR_GREEN: return COLOR_GREEN;
+ case SWT.COLOR_YELLOW: return COLOR_YELLOW;
+ case SWT.COLOR_BLUE: return COLOR_BLUE;
+ case SWT.COLOR_MAGENTA: return COLOR_MAGENTA;
+ case SWT.COLOR_CYAN: return COLOR_CYAN;
+ case SWT.COLOR_WHITE: return COLOR_WHITE;
+ }
+ return COLOR_BLACK;
+}
+
+/**
+ * Returns a reasonable font for applications to use.
+ * On some platforms, this will match the "default font"
+ * or "system font" if such can be found. This font
+ * should not be free'd because it was allocated by the
+ * system, not the application.
+ * <p>
+ * Typically, applications which want the default look
+ * should simply not set the font on the widgets they
+ * create. Widgets are always created with the correct
+ * default font for the class of user-interface component
+ * they represent.
+ * </p>
+ *
+ * @return a font
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public Font getSystemFont () {
+ checkDevice ();
+ return null;
+}
+
+protected void init () {
+ COLOR_BLACK = new Color (this, 0,0,0);
+ COLOR_DARK_RED = new Color (this, 0x80,0,0);
+ COLOR_DARK_GREEN = new Color (this, 0,0x80,0);
+ COLOR_DARK_YELLOW = new Color (this, 0x80,0x80,0);
+ COLOR_DARK_BLUE = new Color (this, 0,0,0x80);
+ COLOR_DARK_MAGENTA = new Color (this, 0x80,0,0x80);
+ COLOR_DARK_CYAN = new Color (this, 0,0x80,0x80);
+ COLOR_GRAY = new Color (this, 0xC0,0xC0,0xC0);
+ COLOR_DARK_GRAY = new Color (this, 0x80,0x80,0x80);
+ COLOR_RED = new Color (this, 0xFF,0,0);
+ COLOR_GREEN = new Color (this, 0,0xFF,0);
+ COLOR_YELLOW = new Color (this, 0xFF,0xFF,0);
+ COLOR_BLUE = new Color (this, 0,0,0xFF);
+ COLOR_MAGENTA = new Color (this, 0xFF,0,0xFF);
+ COLOR_CYAN = new Color (this, 0,0xFF,0xFF);
+ COLOR_WHITE = new Color (this, 0xFF,0xFF,0xFF);
+}
+
+/**
+ * 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
+ *
+ * @private
+ */
+public abstract int internal_new_GC (GCData data);
+
+/**
+ * Invokes platform specific functionality to dispose a GC handle.
+ * <p>
+ * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
+ * API for <code>Device</code>. It is marked public only so that it
+ * can be shared within the packages provided by SWT. It is not
+ * available on all platforms, and should never be called from
+ * application code.
+ * </p>
+ *
+ * @param handle the platform specific GC handle
+ * @param data the platform specific GC data
+ *
+ * @private
+ */
+public abstract void internal_dispose_GC (int handle, GCData data);
+
+/**
+ * Returns <code>true</code> if the device has been disposed,
+ * and <code>false</code> otherwise.
+ * <p>
+ * This method gets the dispose state for the device.
+ * When a device has been disposed, it is an error to
+ * invoke any other method using the device.
+ *
+ * @return <code>true</code> when the device is disposed and <code>false</code> otherwise
+ */
+public boolean isDisposed () {
+ return disposed;
+}
+
+void new_Object (Object object) {
+ 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;
+}
+
+protected void release () {
+ if (gdkColors != null) {
+ int colormap = OS.gdk_colormap_get_system();
+ int [] pixel = new int [1];
+ for (int i = 0; i < gdkColors.length; i++) {
+ GdkColor color = gdkColors [i];
+ if (color != null) {
+ while (colorRefCount [i] > 0) {
+ OS.gdk_color_free(color);
+ --colorRefCount [i];
+ }
+ }
+ }
+ }
+ gdkColors = null;
+ colorRefCount = null;
+ COLOR_BLACK = COLOR_DARK_RED = COLOR_DARK_GREEN = COLOR_DARK_YELLOW = COLOR_DARK_BLUE =
+ COLOR_DARK_MAGENTA = COLOR_DARK_CYAN = COLOR_GRAY = COLOR_DARK_GRAY = COLOR_RED =
+ COLOR_GREEN = COLOR_YELLOW = COLOR_BLUE = COLOR_MAGENTA = COLOR_CYAN = COLOR_WHITE = null;
+}
+
+/**
+ * If the underlying window system supports printing warning messages
+ * to the console, setting warnings to <code>true</code> prevents these
+ * messages from being printed. If the argument is <code>false</code>
+ * message printing is not blocked.
+ *
+ * @param warnings <code>true</code>if warnings should be handled, 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/gtk/org/eclipse/swt/graphics/DeviceData.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/DeviceData.java
new file mode 100644
index 0000000000..4ed07ebc16
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/DeviceData.java
@@ -0,0 +1,24 @@
+package org.eclipse.swt.graphics;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+
+public class DeviceData {
+ /*
+ * Motif only fields.
+ */
+ public String display_name;
+ public String application_name;
+ public String application_class;
+
+ /*
+ * 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/gtk/org/eclipse/swt/graphics/Font.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Font.java
new file mode 100644
index 0000000000..89d6132939
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Font.java
@@ -0,0 +1,209 @@
+package org.eclipse.swt.graphics;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.internal.*;
+import org.eclipse.swt.internal.gtk.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * 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
+ */
+public final class Font {
+ /**
+ * the handle to the OS font resource
+ * (Warning: This field is platform dependent)
+ */
+ public int handle;
+Font() {
+}
+/**
+ * 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 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 display, FontData fd) {
+ if (fd == null) error(SWT.ERROR_NULL_ARGUMENT);
+
+ String xlfd = fd.getXlfd();
+ byte[] buffer = Converter.wcsToMbcs(null, xlfd, true);
+ handle = OS.gdk_font_load(buffer);
+ if (handle == 0) {
+ int hStyle = OS.gtk_widget_get_default_style();
+ GtkStyle gtkStyle = new GtkStyle();
+ OS.memmove(gtkStyle, hStyle, GtkStyle.sizeof);
+ handle = OS.gdk_font_ref(gtkStyle.font);
+ }
+}
+/**
+ * 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 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 display, String fontFamily, int height, int style) {
+ if (fontFamily == null) error(SWT.ERROR_NULL_ARGUMENT);
+ FontData fd = new FontData(fontFamily, height, style);
+ byte[] buffer = Converter.wcsToMbcs(null, fd.getXlfd(), true);
+ handle = OS.gdk_font_load(buffer);
+ if (handle == 0) {
+ int hStyle = OS.gtk_widget_get_default_style();
+ GtkStyle gtkStyle = new GtkStyle();
+ OS.memmove(gtkStyle, hStyle, GtkStyle.sizeof);
+ handle = OS.gdk_font_ref(gtkStyle.font);
+ }
+}
+/**
+ * Disposes of the operating system resources associated with
+ * the font. Applications must dispose of all fonts which
+ * they allocate.
+ */
+public void dispose() {
+ if (handle != 0) OS.gdk_font_unref(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;
+ return OS.gdk_font_equal(handle, ((Font)object).handle);
+}
+void error(int code) {
+ throw new SWTError (code);
+}
+
+/**
+ * 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() {
+ int index=0;
+ int fnames = getFontNameList(handle);
+ int nfonts = OS.g_slist_length(fnames);
+ FontData[] answer = new FontData[nfonts];
+ for (int i=0; i<nfonts; i++) {
+ FontData data = new FontData();
+
+ int name = OS.g_slist_nth_data(fnames, index);
+ int length = OS.strlen(name);
+ byte [] buffer1 = new byte[length];
+ OS.memmove(buffer1, name, length);
+ char [] buffer2 = Converter.mbcsToWcs (null, buffer1);
+ String fontname = new String (buffer2, 0, buffer2.length);
+ data.setXlfd(fontname);
+
+ // Wild guess, 'a' looks average enough
+ data.averageWidth = OS.gdk_char_width(handle, (byte)'a');
+
+ // Wild guess, a progressive font should probably have A wider than l
+ int widthA = OS.gdk_char_width(handle, (byte)'A');
+ int widthl = OS.gdk_char_width(handle, (byte)'l');
+ if (widthA == widthl) data.spacing = "m";
+ else data.spacing = "p";
+
+ answer[i] = data;
+ }
+ return answer;
+}
+static int getFontNameList(int handle) {
+ int[] mem = new int[7];
+ OS.memmove(mem, handle, 7*4);
+ int type = mem[0];
+ int ascent = mem[1];
+ int descent = mem[2];
+ int xfont =mem [3];
+ int xdisplay = mem[4];
+ int ref_count = mem[5];
+ int names = mem[6];
+ return names;
+}
+public static Font gtk_new(int handle) {
+ Font font = new Font();
+ font.handle = handle;
+ return font;
+}
+/**
+ * Returns an integer hash code for the receiver. Any two
+ * objects which return <code>true</code> when passed to
+ * <code>equals</code> must return the same value for this
+ * method.
+ *
+ * @return the receiver's hash
+ *
+ * @see #equals
+ */
+public int hashCode() {
+ return handle;
+}
+/**
+ * Returns <code>true</code> if the 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;
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/FontData.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/FontData.java
new file mode 100644
index 0000000000..f1794991f0
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/FontData.java
@@ -0,0 +1,546 @@
+package org.eclipse.swt.graphics;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+
+import org.eclipse.swt.*;
+
+/**
+ * Instances of this class describe operating system fonts.
+ * Only the public API of this type is platform independent.
+ * <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
+ */
+public final class FontData {
+ /**
+ * The company that produced the font
+ * Warning: This field is platform dependent.
+ */
+ public String foundry;
+ /**
+ * The common name of the font
+ * Warning: This field is platform dependent.
+ */
+ public String fontFamily;
+ /**
+ * The weight ("normal", "bold")
+ * Warning: This field is platform dependent.
+ */
+ public String weight;
+ /**
+ * The slant ("o" for oblique, "i" for italic)
+ * Warning: This field is platform dependent.
+ */
+ public String slant;
+ /**
+ * The set width of the font
+ * Warning: This field is platform dependent.
+ */
+ public String setWidth;
+ /**
+ * Additional font styles
+ * Warning: This field is platform dependent.
+ */
+ public String addStyle;
+ /**
+ * The height of the font in pixels
+ * Warning: This field is platform dependent.
+ */
+ public int pixels;
+ /**
+ * The height of the font in tenths of a point
+ * Warning: This field is platform dependent.
+ */
+ public int points;
+ /**
+ * The horizontal screen resolution for which the font was designed
+ * Warning: This field is platform dependent.
+ */
+ public int horizontalResolution;
+ /**
+ * The vertical screen resolution for which the font was designed
+ * Warning: This field is platform dependent.
+ */
+ public int verticalResolution;
+ /**
+ * The font spacing ("m" for monospace, "p" for proportional)
+ * Warning: This field is platform dependent.
+ */
+ public String spacing;
+ /**
+ * The average character width for the font
+ * Warning: This field is platform dependent.
+ */
+ public int averageWidth;
+ /**
+ * The ISO character set registry
+ * Warning: This field is platform dependent.
+ */
+ public String characterSetRegistry;
+ /**
+ * The ISO character set name
+ * Warning: This field is platform dependent.
+ */
+ public String characterSetName;
+ /**
+ * The locales of the font
+ * (Warning: These fields are platform dependent)
+ */
+ String lang, country, variant;
+
+/**
+ * Constructs a new un-initialized font data.
+ */
+public FontData () {
+}
+/**
+ * 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) error(SWT.ERROR_NULL_ARGUMENT);
+ int start = 0;
+ int end = string.indexOf('|');
+ if (end == -1) error(SWT.ERROR_NULL_ARGUMENT);
+ String version1 = string.substring(start, end);
+
+ start = end + 1;
+ end = string.indexOf('|', start);
+ if (end == -1) error(SWT.ERROR_NULL_ARGUMENT);
+ String name = string.substring(start, end);
+
+ start = end + 1;
+ end = string.indexOf('|', start);
+ if (end == -1) error(SWT.ERROR_NULL_ARGUMENT);
+ int height = 0;
+ try {
+ height = Integer.parseInt(string.substring(start, end));
+ } catch (NumberFormatException e) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+
+ start = end + 1;
+ end = string.indexOf('|', start);
+ if (end == -1) error(SWT.ERROR_NULL_ARGUMENT);
+ int style = 0;
+ try {
+ style = Integer.parseInt(string.substring(start, end));
+ } catch (NumberFormatException e) {
+ error(SWT.ERROR_NULL_ARGUMENT);
+ }
+
+ start = end + 1;
+ end = string.indexOf('|', start);
+ if (end == -1) {
+ setName(name);
+ setHeight(height);
+ setStyle(style);
+ return;
+ }
+ String platform = string.substring(start, end);
+
+ start = end + 1;
+ end = string.indexOf('|', start);
+ if (end == -1) {
+ setName(name);
+ setHeight(height);
+ setStyle(style);
+ return;
+ }
+ String version2 = string.substring(start, end);
+
+ if (platform.equals("MOTIF") && version2.equals("1")) {
+ start = end + 1;
+ end = string.length();
+ if (end == -1) {
+ setName(name);
+ setHeight(height);
+ setStyle(style);
+ return;
+ }
+ String xlfd = string.substring(start, end);
+ setXlfd(xlfd);
+ return;
+ }
+ setName(name);
+ setHeight(height);
+ setStyle(style);
+}
+/**
+ * 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);
+ if (height < 0) error(SWT.ERROR_INVALID_ARGUMENT);
+ int dash = name.indexOf('-');
+ if (dash != -1) {
+ foundry = name.substring(0, dash);
+ fontFamily = name.substring(dash + 1);
+ } else {
+ fontFamily = name;
+ }
+ points = height * 10;
+ if ((style & SWT.BOLD) != 0) {
+ weight = "bold";
+ } else {
+ weight = "medium";
+ }
+ if ((style & SWT.ITALIC) != 0) {
+ slant = "i";
+ } else {
+ slant = "r";
+ }
+}
+
+
+
+/*
+ * Public getters
+ */
+
+/**
+ * Returns the height of the receiver in points.
+ *
+ * @return the height of this FontData
+ *
+ * @see #setHeight
+ */
+public int getHeight() {
+ return points / 10;
+}
+
+/**
+ * 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() {
+ StringBuffer buffer = new StringBuffer();
+ if (foundry != null) {
+ buffer.append(foundry);
+ buffer.append("-");
+ }
+ if (fontFamily != null) buffer.append(fontFamily);
+ return buffer.toString();
+}
+
+/**
+ * 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 = 0;
+ if (weight.equals("bold"))
+ style |= SWT.BOLD;
+ if (slant.equals("i"))
+ style |= SWT.ITALIC;
+ return style;
+}
+
+/**
+ * WARNING: This method is only public on GTK.
+ * We need this in FontDialog, so we can't just get rid of it or make it private.
+ */
+public String getXlfd() {
+ String s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14;
+ s1 = s2 = s3 = s4 = s5 = s6 = s7 = s8 = s9 = s10 = s11 = s12 = s13 = s14 = "*";
+
+ if (foundry != null) s1 = foundry;
+ if (fontFamily != null) s2 = fontFamily;
+ if (weight != null) s3 = weight;
+ if (slant != null) s4 = slant;
+ if (setWidth != null) s5 = setWidth;
+ if (addStyle != null) s6 = addStyle;
+ if (pixels != 0) s7 = Integer.toString(pixels);
+ if (points != 0) s8 = Integer.toString(points);
+ if (horizontalResolution != 0) s9 = Integer.toString(horizontalResolution);
+ if (verticalResolution != 0) s10 = Integer.toString(verticalResolution);
+ if (spacing != null) s11 = spacing;
+// The following line has been intentionally commented.
+// we don not know the exact average width as in the font definition,
+// so if someone tries to get a similar font, they'd get something weird
+// if (averageWidth != 0) s12 = Integer.toString(averageWidth);
+ if (characterSetRegistry != null) s13 = characterSetRegistry;
+ if (characterSetName != null) s14 = characterSetName;
+
+ String xlfd = "-" + s1+ "-" + s2 + "-" + s3 + "-" + s4 + "-" + s5 + "-" + s6 + "-" + s7 + "-" + s8 + "-"
+ + s9 + "-" + s10 + "-" + s11 + "-" + s12 + "-" + s13 + "-" + s14;
+ return xlfd;
+}
+public static FontData gtk_new(String xlfd) {
+ FontData fontData = new FontData();
+ fontData.setXlfd(xlfd);
+ return fontData;
+}
+/**
+ * Returns an integer hash code for the receiver. Any two
+ * objects which 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 getXlfd().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) error(SWT.ERROR_INVALID_ARGUMENT);
+ points = height * 10;
+}
+
+/**
+ * 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 which there are multiple character sets for a
+ * given language/country locale, the variant portion of the
+ * locale will determine the character set.
+ * </p>
+ *
+ * @param locale the <code>String</code> representing a Locale object
+ * @see java.util.Locale#toString
+ */
+public void setLocale(String locale) {
+ lang = country = variant = null;
+ if (locale != null) {
+ char sep = '_';
+ int length = locale.length();
+ int firstSep, secondSep;
+
+ firstSep = locale.indexOf(sep);
+ if (firstSep == -1) {
+ firstSep = secondSep = length;
+ } else {
+ secondSep = locale.indexOf(sep, firstSep + 1);
+ if (secondSep == -1) secondSep = length;
+ }
+ if (firstSep > 0) lang = locale.substring(0, firstSep);
+ if (secondSep > firstSep + 1) country = locale.substring(firstSep + 1, secondSep);
+ if (length > secondSep + 1) variant = locale.substring(secondSep + 1);
+ }
+}
+/**
+ * Sets the name of the receiver.
+ * <p>
+ * Some platforms support font foundries. On these platforms, the name
+ * of the font specified in setName() may have one of the following forms:
+ * <ol>
+ * <li>a face name (for example, "courier")</li>
+ * <li>a foundry followed by a dash ("-") followed by a face name (for example, "adobe-courier")</li>
+ * </ol>
+ * In either case, the name returned from getName() will include the
+ * foundry.
+ * </p>
+ * <p>
+ * On platforms that do not support font foundries, only the face name
+ * (for example, "courier") is used in <code>setName()</code> and
+ * <code>getName()</code>.
+ * </p>
+ *
+ * @param name the name of the font data (must not be null)
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - when the font name is null</li>
+ * </ul>
+ *
+ * @see #getName
+ */
+public void setName(String name) {
+ if (name == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ int dash = name.indexOf('-');
+ if (dash != -1) {
+ foundry = name.substring(0, dash);
+ fontFamily = name.substring(dash + 1);
+ } else {
+ fontFamily = name;
+ }
+}
+/**
+ * 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.
+ *
+ * @param style the new style for this <code>FontData</code>
+ *
+ * @see #getStyle
+ */
+public void setStyle(int style) {
+ if ((style & SWT.BOLD) == SWT.BOLD)
+ weight = "bold";
+ else
+ weight = "medium";
+ if ((style & SWT.ITALIC) == SWT.ITALIC)
+ slant = "i";
+ else
+ slant = "r";
+}
+void setXlfd(String xlfd) {
+ int start, stop;
+ start = 1;
+ stop = xlfd.indexOf ("-", start);
+ foundry = xlfd.substring(start, stop);
+ if (foundry.equals("*")) foundry = null;
+ start = stop + 1;
+ stop = xlfd.indexOf ("-", start);
+ fontFamily = xlfd.substring(start, stop);
+ if (fontFamily.equals("*")) fontFamily = null;
+ start = stop + 1;
+ stop = xlfd.indexOf ("-", start);
+ weight = xlfd.substring(start, stop);
+ if (weight.equals("*")) weight = null;
+ start = stop + 1;
+ stop = xlfd.indexOf ("-", start);
+ slant = xlfd.substring(start, stop);
+ if (slant.equals("*")) slant = null;
+ start = stop + 1;
+ stop = xlfd.indexOf ("-", start);
+ setWidth = xlfd.substring(start, stop);
+ if (setWidth.equals("*")) setWidth = null;
+ start = stop + 1;
+ stop = xlfd.indexOf ("-", start);
+ addStyle = xlfd.substring(start, stop);
+ if (addStyle.equals("*")) addStyle = null;
+ start = stop + 1;
+ stop = xlfd.indexOf ("-", start);
+ String s = xlfd.substring(start, stop);
+ if (!s.equals("") && !s.equals("*"))
+ pixels = Integer.parseInt(s);
+ start = stop + 1;
+ stop = xlfd.indexOf ("-", start);
+ s = xlfd.substring(start, stop);
+ if (!s.equals("") && !s.equals("*"))
+ points = Integer.parseInt(s);
+ start = stop + 1;
+ stop = xlfd.indexOf ("-", start);
+ s = xlfd.substring(start, stop);
+ if (!s.equals("") && !s.equals("*"))
+ horizontalResolution = Integer.parseInt(s);
+ start = stop + 1;
+ stop = xlfd.indexOf ("-", start);
+ s = xlfd.substring(start, stop);
+ if (!s.equals("") && !s.equals("*"))
+ verticalResolution = Integer.parseInt(s);
+ start = stop + 1;
+ stop = xlfd.indexOf ("-", start);
+ spacing = xlfd.substring(start, stop);
+ start = stop + 1;
+ stop = xlfd.indexOf ("-", start);
+ s = xlfd.substring(start, stop);
+ if (!s.equals("") && !s.equals("*"))
+ averageWidth = Integer.parseInt(s);
+ start = stop + 1;
+ stop = xlfd.indexOf ("-", start);
+ characterSetRegistry = xlfd.substring(start, stop);
+ if (characterSetRegistry.equals("*")) characterSetRegistry = null;
+ start = stop + 1;
+ stop = xlfd.indexOf ("-", start);
+ characterSetName = xlfd.substring(start);
+ if (characterSetName.equals("*")) characterSetName = null;
+}
+/**
+ * Returns a string representation of the receiver which is suitable
+ * for constructing an equivalent instance using the
+ * <code>FontData(String)</code> constructor.
+ *
+ * @return a string representation of the FontData
+ *
+ * @see FontData
+ */
+public String toString() {
+ return "1|" + fontFamily + "|" + getHeight() + "|" + getStyle() + "|" +
+ "GTK|1|" + getXlfd();
+}
+
+/**
+ * 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 FontData) &&
+ getXlfd().equals(((FontData)object).getXlfd()));
+}
+void error(int code) {
+ throw new SWTError(code);
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/FontMetrics.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/FontMetrics.java
new file mode 100644
index 0000000000..b1bd432690
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/FontMetrics.java
@@ -0,0 +1,122 @@
+package org.eclipse.swt.graphics;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+
+import org.eclipse.swt.internal.gtk.*;
+
+/**
+ * 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
+ */
+
+public final class FontMetrics {
+ int ascent, descent, averageCharWidth, leading, height;
+FontMetrics() {
+}
+/**
+ * Compares the argument to the receiver, and returns true
+ * if they represent the <em>same</em> object using a class
+ * specific comparison.
+ *
+ * @param object the object to compare with this object
+ * @return <code>true</code> if the object is the same as this object and <code>false</code> otherwise
+ *
+ * @see #hashCode
+ */
+public boolean equals (Object object) {
+ if (object == this) return true;
+ if (!(object instanceof FontMetrics)) return false;
+ FontMetrics metrics = (FontMetrics)object;
+ return ascent == metrics.ascent && descent == metrics.descent &&
+ averageCharWidth == metrics.averageCharWidth && leading == metrics.leading &&
+ height == metrics.height;
+}
+/**
+ * Returns the ascent of the font described by the receiver. A
+ * font's <em>ascent</em> is the distance from the baseline to the
+ * top of actual characters, not including any of the leading area,
+ * measured in pixels.
+ *
+ * @return the ascent of the font
+ */
+public int getAscent() {
+ return ascent;
+}
+/**
+ * Returns the average character width, measured in pixels,
+ * of the font described by the receiver.
+ *
+ * @return the average character width of the font
+ */
+public int getAverageCharWidth() {
+ return averageCharWidth;
+}
+/**
+ * Returns the descent of the font described by the receiver. A
+ * font's <em>descent</em> is the distance from the baseline to the
+ * bottom of actual characters, not including any of the leading area,
+ * measured in pixels.
+ *
+ * @return the descent of the font
+ */
+public int getDescent() {
+ return descent;
+}
+/**
+ * Returns the height of the font described by the receiver,
+ * measured in pixels. A font's <em>height</em> is the sum of
+ * its ascent, descent and leading area.
+ *
+ * @return the height of the font
+ *
+ * @see #getAscent
+ * @see #getDescent
+ * @see #getLeading
+ */
+public int getHeight() {
+ return height;
+}
+/**
+ * Returns the leading area of the font described by the
+ * receiver. A font's <em>leading area</em> is the space
+ * above its ascent which may include accents or other marks.
+ *
+ * @return the leading space of the font
+ */
+public int getLeading() {
+ return leading;
+}
+public static FontMetrics gtk_new(int fontHandle) {
+ GdkFont f = new GdkFont();
+ OS.memmove (f, fontHandle, GdkFont.sizeof);
+
+ FontMetrics fontMetrics = new FontMetrics();
+ fontMetrics.ascent = f.ascent;
+ fontMetrics.descent = f.descent;
+ fontMetrics.averageCharWidth = OS.gdk_char_width(fontHandle, (byte)'a');
+ fontMetrics.leading = 3;
+ fontMetrics.height = fontMetrics.ascent+fontMetrics.descent+3;
+ return fontMetrics;
+}
+/**
+ * Returns an integer hash code for the receiver. Any two
+ * objects which return <code>true</code> when passed to
+ * <code>equals</code> must return the same value for this
+ * method.
+ *
+ * @return the receiver's hash
+ *
+ * @see #equals
+ */
+public int hashCode() {
+ return ascent ^ descent ^ averageCharWidth ^ leading ^ height;
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java
new file mode 100644
index 0000000000..6b9b89ee9c
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java
@@ -0,0 +1,1697 @@
+package org.eclipse.swt.graphics;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+
+import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.internal.gtk.*;
+import org.eclipse.swt.internal.*;
+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>.
+ * <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>
+ *
+ * @see org.eclipse.swt.events.PaintEvent
+ */
+public final class GC {
+ /**
+ * the handle to the OS device context
+ * (Warning: This field is platform dependent)
+ */
+ public int handle;
+ Drawable drawable;
+ GCData data;
+
+
+/*
+ * === Constructors ===
+ */
+
+GC() {
+}
+
+/**
+ * Constructs a new instance of this class which has been
+ * configured to draw on the specified drawable. Sets the
+ * foreground and background color 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_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>
+ */
+public GC(Drawable drawable) {
+ if (drawable == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+
+ data = new GCData();
+ handle = drawable.internal_new_GC(data);
+ this.drawable = drawable;
+
+ // The colors we get from the widget are not always right.
+ // Get the default GTK_STATE_NORMAL colors
+ setBackground( DefaultGtkStyle.instance().backgroundColorNORMAL() );
+ setForeground( DefaultGtkStyle.instance().foregroundColorNORMAL() );
+
+
+ // Feature in GDK.
+ // Sometimes, gdk_gc_new() doesn't get the font from the control,
+ // and also, some controls don't contain a font; so when the GC
+ // was created in internal_new_gc(), the font might or might not
+ // be set; if the font isn't there, just fall back to default.
+ GdkGCValues values = new GdkGCValues();
+ OS.gdk_gc_get_values(handle, values);
+ if (values.font == 0) {
+ OS.gdk_gc_set_font(handle, DefaultGtkStyle.instance().loadDefaultFont() );
+ }
+
+ if (data.image != null) {
+ data.image.memGC = this;
+ /*
+ * The transparent pixel mask might change when drawing on
+ * the image. Destroy it so that it is regenerated when
+ * necessary.
+ */
+ //if (image.transparentPixel != -1) image.destroyMask();
+ }
+
+}
+
+
+
+/**
+ * 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>
+ */
+/*
+ * === Access - Get/Set ===
+ */
+
+public Color getBackground() {
+ if (handle == 0) error(SWT.ERROR_WIDGET_DISPOSED);
+ GdkColor gdkColor = _getBackgroundGdkColor();
+ return Color.gtk_new(gdkColor);
+}
+/**
+ * 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 (color == null) error(SWT.ERROR_NULL_ARGUMENT);
+ if (color.handle == null) error(SWT.ERROR_NULL_ARGUMENT);
+ if (handle == 0) error(SWT.ERROR_WIDGET_DISPOSED);
+ OS.gdk_gc_set_background(handle, color.handle);
+}
+
+/**
+ * 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) error(SWT.ERROR_WIDGET_DISPOSED);
+ GdkColor gdkColor = _getForegroundGdkColor();
+ return Color.gtk_new(gdkColor);
+}
+
+/**
+ * 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) error(SWT.ERROR_WIDGET_DISPOSED);
+ if (color == null) error(SWT.ERROR_NULL_ARGUMENT);
+ if (color.handle == null) error(SWT.ERROR_NULL_ARGUMENT);
+ OS.gdk_gc_set_foreground(handle, color.handle);
+}
+
+
+
+
+
+
+
+/**
+ * Returns the <em>advance width</em> of the specified character in
+ * the font which is currently selected into the receiver.
+ * <p>
+ * The advance width is defined as the horizontal distance the cursor
+ * should move after printing the character in the selected font.
+ * </p>
+ *
+ * @param ch the character to measure
+ * @return the distance in the x direction to move past the character before painting the next
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+/*
+ * === Access - Get - Calculated ===
+ */
+
+public int getAdvanceWidth(char ch) {
+ byte[] charBuffer = Converter.wcsToMbcs(null, new char[] { ch });
+ return OS.gdk_char_width(_getGCFont(), charBuffer[0]);
+}
+/**
+ * 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) {
+ byte[] charBuffer = Converter.wcsToMbcs(null, new char[] { ch });
+ int[] lbearing = new int[1];
+ int[] rbearing = new int[1];
+ int[] unused = new int[1];
+ OS.gdk_string_extents(_getGCFont(), charBuffer, lbearing, rbearing, unused, unused, unused);
+ return rbearing[0] - lbearing[0];
+}
+/**
+ * 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 (data.clipRgn == 0) {
+ int[] width = new int[1]; int[] height = new int[1];
+ int[] unused = new int[1];
+ OS.gdk_window_get_geometry(data.drawable, unused, unused, width, height, unused);
+ return new Rectangle(0, 0, width[0], height[0]);
+ }
+ GdkRectangle rect = new GdkRectangle();
+ OS.gdk_region_get_clipbox(data.clipRgn, rect);
+ return new Rectangle(rect.x, rect.y, rect.width, rect.height);
+}
+/**
+ * Sets the region managed by the argument to the current
+ * clipping region of the receiver.
+ *
+ * @param region the region to fill with the clipping region
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the region is null</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public void getClipping(Region region) {
+ if (region == null) error(SWT.ERROR_NULL_ARGUMENT);
+ int hRegion = region.handle;
+ if (data.clipRgn == 0) {
+ int[] width = new int[1]; int[] height = new int[1];
+ int[] unused = new int[1];
+ OS.gdk_window_get_geometry(data.drawable, unused, unused, width, height, unused);
+ hRegion = OS.gdk_region_new();
+ GdkRectangle rect = new GdkRectangle();
+ rect.x = 0; rect.y = 0;
+ rect.width = (short)width[0]; rect.height = (short)height[0];
+ region.handle = OS.gdk_region_union_with_rect(hRegion, rect);
+ return;
+ }
+ hRegion = OS.gdk_region_new();
+ region.handle = OS.gdk_regions_union(data.clipRgn, hRegion);
+}
+/**
+ * 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() {
+ return Font.gtk_new(_getGCFont());
+}
+/**
+ * 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>
+ */
+// Not done
+public FontMetrics getFontMetrics() {
+ int fontHandle = _getGCFont();
+ if (fontHandle==0) {
+ error(SWT.ERROR_UNSPECIFIED);
+ }
+ GdkFont gdkFont = new GdkFont();
+ OS.memmove(gdkFont, fontHandle, GdkFont.sizeof);
+ byte [] w = Converter.wcsToMbcs (null, "w", true);
+ return FontMetrics.gtk_new(fontHandle);
+}
+
+/**
+ * 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() {
+ 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() {
+ GdkGCValues values = new GdkGCValues();
+ OS.gdk_gc_get_values(handle, values);
+ return values.line_width;
+}
+/**
+ * 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() {
+ GdkGCValues values = new GdkGCValues();
+ OS.gdk_gc_get_values(handle, values);
+ return values.function == OS.GDK_XOR;
+}
+/**
+ * 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() {
+ return data.clipRgn != 0;
+}
+
+
+/**
+ * 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 (data.clipRgn == 0) data.clipRgn = OS.gdk_region_new();
+ GdkRectangle rect = new GdkRectangle();
+ rect.x = (short)x; rect.y = (short)y;
+ rect.width = (short)width; rect.height = (short)height;
+ OS.gdk_gc_set_clip_rectangle(handle, rect);
+ data.clipRgn = OS.gdk_regions_subtract(data.clipRgn, data.clipRgn);
+ data.clipRgn = OS.gdk_region_union_with_rect(data.clipRgn, rect);
+}
+/**
+ * Sets the area of the receiver which can be changed
+ * by drawing operations to the rectangular area specified
+ * by the argument.
+ *
+ * @param rect the clipping rectangle
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public void setClipping(Rectangle rect) {
+ if (rect == null) error(SWT.ERROR_NULL_ARGUMENT);
+ 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.
+ *
+ * @param rect the clipping region.
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public void setClipping(Region region) {
+ if (data.clipRgn == 0) data.clipRgn = OS.gdk_region_new();
+ if (region == null) {
+ data.clipRgn = OS.gdk_regions_subtract(data.clipRgn, data.clipRgn);
+ OS.gdk_gc_set_clip_mask(handle, OS.GDK_NONE);
+ } else {
+ data.clipRgn = OS.gdk_regions_subtract(data.clipRgn, data.clipRgn);
+ data.clipRgn = OS.gdk_regions_union(region.handle, data.clipRgn);
+ OS.gdk_gc_set_clip_region(handle, region.handle);
+ }
+}
+/**
+ * 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) {
+ int fontHandle = 0;
+ if (font == null) {
+ GtkStyle gtkStyle = new GtkStyle();
+ int style = OS.gtk_widget_get_default_style();
+ OS.memmove(gtkStyle, style, GtkStyle.sizeof);
+ fontHandle = gtkStyle.font;
+ } else {
+ fontHandle = font.handle;
+ }
+ OS.gdk_gc_set_font(handle, fontHandle);
+}
+
+/**
+ * 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 SWTException <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public void setLineStyle(int lineStyle) {
+ switch (lineStyle) {
+ case SWT.LINE_SOLID:
+ this.data.lineStyle = lineStyle;
+ OS.gdk_gc_set_line_attributes(handle, 0, OS.GDK_LINE_SOLID, OS.GDK_CAP_BUTT, OS.GDK_JOIN_MITER);
+ return;
+ case SWT.LINE_DASH:
+ OS.gdk_gc_set_dashes(handle, 0, new byte[] {6, 2}, 2);
+ break;
+ case SWT.LINE_DOT:
+ OS.gdk_gc_set_dashes(handle, 0, new byte[] {3, 1}, 2);
+ break;
+ case SWT.LINE_DASHDOT:
+ OS.gdk_gc_set_dashes(handle, 0, new byte[] {6, 2, 3, 1}, 4);
+ break;
+ case SWT.LINE_DASHDOTDOT:
+ OS.gdk_gc_set_dashes(handle, 0, new byte[] {6, 2, 3, 1, 3, 1}, 6);
+ break;
+ default:
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ this.data.lineStyle = lineStyle;
+ OS.gdk_gc_set_line_attributes(handle, 0, OS.GDK_LINE_DOUBLE_DASH, OS.GDK_CAP_BUTT, OS.GDK_JOIN_MITER);
+}
+/**
+ * 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.
+ *
+ * @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 width) {
+ if (data.lineStyle == SWT.LINE_SOLID) {
+ OS.gdk_gc_set_line_attributes(handle, width, OS.GDK_LINE_SOLID, OS.GDK_CAP_BUTT, OS.GDK_JOIN_MITER);
+ } else {
+ OS.gdk_gc_set_line_attributes(handle, width, OS.GDK_LINE_DOUBLE_DASH, OS.GDK_CAP_BUTT, OS.GDK_JOIN_MITER);
+ }
+}
+/**
+ * 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.
+ *
+ * @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>
+ */
+public void setXORMode(boolean val) {
+ if (val) {
+ OS.gdk_gc_set_function(handle, OS.GDK_XOR);
+ } else {
+ OS.gdk_gc_set_function(handle, OS.GDK_COPY);
+ }
+}
+/**
+ * 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 (string == null) error(SWT.ERROR_NULL_ARGUMENT);
+ byte[] buffer = Converter.wcsToMbcs(null, string, true);
+ int width = OS.gdk_string_width(_getGCFont(), buffer);
+ int height = OS.gdk_string_height(_getGCFont(), buffer);
+ return new Point(width, height);
+}
+/**
+ * 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) {
+ if (string == null) error(SWT.ERROR_NULL_ARGUMENT);
+ byte[] buffer = Converter.wcsToMbcs(null, string, true);
+ int width = OS.gdk_string_width(_getGCFont(), buffer);
+ int height = OS.gdk_string_height(_getGCFont(), buffer);
+ return new Point(width, height);
+}
+
+
+
+/*
+ * === Access - Internal utils ===
+ */
+
+private GdkGCValues _getGCValues() {
+ GdkGCValues values = new GdkGCValues();
+ OS.gdk_gc_get_values(handle, values);
+ return values;
+}
+private GdkColor _getForegroundGdkColor() {
+ GdkGCValues values = _getGCValues();
+ GdkColor color = new GdkColor();
+ color.pixel = values.foreground_pixel;
+ color.red = values.foreground_red;
+ color.green = values.foreground_green;
+ color.blue = values.foreground_blue;
+ return color;
+}
+private GdkColor _getBackgroundGdkColor() {
+ GdkGCValues values = _getGCValues();
+ GdkColor color = new GdkColor();
+ color.pixel = values.background_pixel;
+ color.red = values.background_red;
+ color.green = values.background_green;
+ color.blue = values.background_blue;
+ return color;
+}
+private int _getGCFont() {
+ GdkGCValues values = _getGCValues();
+ if (values.font==0) {
+ SWT.error(SWT.ERROR_UNSPECIFIED);
+ }
+ return values.font;
+}
+
+
+
+/**
+ * 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>
+ */
+/*
+ * === Drawing operations proper ===
+ */
+
+public void copyArea(int srcX, int srcY, int width, int height, int destX, int destY) {
+ OS.gdk_window_copy_area(data.drawable, handle, destX, destY, data.drawable, srcX, srcY, width, height);
+}
+
+/**
+ * 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 IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if any of the width, height or endAngle is zero.</li>
+ * </ul>
+ * @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 endAngle) {
+ if (width < 0) {
+ x = x + width;
+ width = -width;
+ }
+ if (height < 0) {
+ y = y + height;
+ height = -height;
+ }
+ if (width == 0 || height == 0 || endAngle == 0) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ OS.gdk_draw_arc(data.drawable, handle, 0, x, y, width, height, startAngle * 64, endAngle * 64);
+}
+/**
+ * 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 forground 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
+ */
+public void drawFocus(int x, int y, int width, int height) {
+ GtkStyle style = new GtkStyle();
+ int hStyle = OS.gtk_widget_get_default_style();
+ OS.memmove(style, hStyle, GtkStyle.sizeof);
+ GdkColor color = new GdkColor();
+ color.pixel = style.fg0_pixel;
+ color.red = style.fg0_red;
+ color.green = style.fg0_green;
+ color.blue = style.fg0_blue;
+ GdkGCValues values = new GdkGCValues();
+ OS.gdk_gc_get_values(handle, values);
+ OS.gdk_gc_set_foreground(handle, color);
+ OS.gdk_draw_rectangle(data.drawable, handle, 0, x, y, width, height);
+ color.pixel = values.foreground_pixel;
+ color.red = values.foreground_red;
+ color.green = values.foreground_green;
+ color.blue = values.foreground_blue;
+ OS.gdk_gc_set_foreground(handle, color);
+}
+/**
+ * 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 SWTError <ul>
+ * <li>ERROR_NO_HANDLES - if no handles are available to perform the operation</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public void drawImage(Image image, int x, int y) {
+ if (image == null) error(SWT.ERROR_NULL_ARGUMENT);
+ int pixmap = image.pixmap;
+ int [] unused = new int [1]; int [] width = new int [1]; int [] height = new int [1];
+ OS.gdk_window_get_geometry(pixmap, unused, unused, width, height, unused);
+ drawImage(image, 0, 0, width[0], height[0], x, y, width[0], height[0]);
+}
+
+/**
+ * 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 of the given coordinates
+ * are negative or lie outside the bounds of their respective images.
+ *
+ * @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 the given coordinates are outside the bounds of their respective images</li>
+ * </ul>
+ * @exception SWTError <ul>
+ * <li>ERROR_NO_HANDLES - if no handles are available to perform the operation</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight) {
+ /* basic sanity checks */
+ 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 (srcImage == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (srcImage.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+
+ /* source image properties */
+ int[] width = new int[1];
+ int[] height = new int[1];
+ int[] unused = new int[1];
+ OS.gdk_window_get_geometry(srcImage.pixmap, unused, unused, width, height, unused);
+ if ((srcY + srcWidth > width[0]) ||
+ (srcY + srcHeight > height[0])) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+
+ /* Special case: If we don't need to scale, and there is no alpha/mask,
+ * then we can just blit the image inside the X server - no net traffic
+ */
+ boolean needScaling = (srcWidth != destWidth) || (srcHeight != destHeight);
+ boolean simple = !needScaling & (srcImage.mask == 0);
+
+ if (simple) {
+ OS.gdk_draw_pixmap(data.drawable, handle, srcImage.pixmap,
+ srcX, srcY,
+ destX, destY,
+ width[0], height[0]);
+ return;
+ }
+
+
+ /* Fetch a local GdkPixbuf from server */
+ Pixbuffer pixbuf = new Pixbuffer(srcImage);
+
+ /* Scale if necessary */
+ if ((srcWidth != destWidth) || (srcHeight != destHeight)) {
+ double scale_x = (double)destWidth / (double)srcWidth;
+ double scale_y = (double)destHeight / (double)srcHeight;
+ double offset_x = - srcX * scale_x;
+ double offset_y = - srcY * scale_y;
+
+ int destSizePixbuf = GDKPIXBUF.gdk_pixbuf_new (
+ GDKPIXBUF.GDK_COLORSPACE_RGB,
+ true, 8, destWidth, destHeight);
+ GDKPIXBUF.gdk_pixbuf_scale(
+ pixbuf.handle, // src,
+ destSizePixbuf,
+ 0,
+ 0,
+ destWidth, destHeight,
+ offset_x, offset_y,
+ scale_x, scale_y,
+ GDKPIXBUF.GDK_INTERP_BILINEAR);
+ pixbuf.handle = destSizePixbuf;
+ }
+
+ /* Paint it */
+ GDKPIXBUF.gdk_pixbuf_render_to_drawable_alpha(
+ pixbuf.handle,
+ data.drawable,
+ 0, 0,
+ destX, destY,
+ destWidth, destHeight,
+ GDKPIXBUF.GDK_PIXBUF_ALPHA_BILEVEL, 128,
+ GDKPIXBUF.GDK_RGB_DITHER_NORMAL,
+ 0, 0
+ );
+}
+
+/**
+ * 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) {
+ OS.gdk_draw_line (data.drawable, handle, x1, y1, x2, y2);
+}
+/**
+ * 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 (width < 0) {
+ x = x + width;
+ width = -width;
+ }
+ if (height < 0) {
+ y = y + height;
+ height = -height;
+ }
+ OS.gdk_draw_arc(data.drawable, handle, 0, x, y, width, height, 0, 23040);
+}
+/**
+ * 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 (pointArray == null) error(SWT.ERROR_NULL_ARGUMENT);
+ short[] points = new short[pointArray.length];
+ for (int i = 0; i < pointArray.length; i++) {
+ points[i] = (short)pointArray[i];
+ }
+ OS.gdk_draw_polygon(data.drawable, handle, 0, points, points.length / 2);
+}
+/**
+ * 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 (pointArray == null) error(SWT.ERROR_NULL_ARGUMENT);
+ short[] points = new short[pointArray.length];
+ for (int i = 0; i < pointArray.length; i++) {
+ points[i] = (short)pointArray[i];
+ }
+ OS.gdk_draw_lines(data.drawable, handle, points, points.length / 2);
+}
+/**
+ * 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 (width < 0) {
+ x = x + width;
+ width = -width;
+ }
+ if (height < 0) {
+ y = y + height;
+ height = -height;
+ }
+ OS.gdk_draw_rectangle(data.drawable, handle, 0, x, y, width, height);
+}
+/**
+ * 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) 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.
+ *
+ * @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 horizontal diameter of the arc at the four corners
+ * @param arcHeight the vertical diameter of the arc at the four corners
+ *
+ * @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) {
+ 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;
+
+ int naw2 = Compatibility.floor(naw, 2);
+ int nah2 = Compatibility.floor(nah, 2);
+
+ OS.gdk_draw_arc(data.drawable, handle, 0, nx, ny, naw, nah, 5760, 5760);
+ OS.gdk_draw_arc(data.drawable, handle, 0, nx, ny + nh - nah, naw, nah, 11520, 5760);
+ OS.gdk_draw_arc(data.drawable, handle, 0, nx + nw - naw, ny + nh - nah, naw, nah, 17280, 5760);
+ OS.gdk_draw_arc(data.drawable, handle, 0, nx + nw - naw, ny, naw, nah, 0, 5760);
+ OS.gdk_draw_line(data.drawable, handle, nx + naw2, ny, nx + nw - naw2, ny);
+ OS.gdk_draw_line(data.drawable, handle, nx,ny + nah2, nx, ny + nh - nah2);
+ OS.gdk_draw_line(data.drawable, handle, nx + naw2, ny + nh, nx + nw - naw2, ny + nh);
+ OS.gdk_draw_line(data.drawable, handle, nx + nw, ny + nah2, nx + nw, ny + nh - nah2);
+}
+/**
+ * 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 (string == null) error(SWT.ERROR_NULL_ARGUMENT);
+ byte[] buffer = Converter.wcsToMbcs(null, string, true);
+ byte[] buffer1 = Converter.wcsToMbcs(null, "Y", true);
+ int[] unused = new int[1];
+ int[] width = new int[1];
+ int[] ascent = new int[1];
+ int[] average_ascent = new int [1];
+ int fontHandle = _getGCFont();
+ OS.gdk_string_extents(fontHandle, buffer, unused, unused, width, ascent, unused);
+ OS.gdk_string_extents(fontHandle, buffer1, unused, unused, unused, average_ascent, unused);
+ if (ascent[0]<average_ascent[0]) ascent[0] = average_ascent[0];
+ if (!isTransparent) {
+ int height = OS.gdk_string_height(fontHandle, buffer);
+ GdkGCValues values = new GdkGCValues();
+ OS.gdk_gc_get_values(handle, values);
+ GdkColor color = new GdkColor();
+ color.pixel = values.background_pixel;
+ color.red = values.background_red;
+ color.green = values.background_green;
+ color.blue = values.background_blue;
+ OS.gdk_gc_set_foreground(handle, color);
+ OS.gdk_draw_rectangle(data.drawable, handle, 1, x, y, width[0], height);
+ color.pixel = values.foreground_pixel;
+ color.red = values.foreground_red;
+ color.green = values.foreground_green;
+ color.blue = values.foreground_blue;
+ OS.gdk_gc_set_foreground(handle, color);
+ }
+ OS.gdk_draw_string(data.drawable, fontHandle, handle, x, y + ascent[0], buffer);
+}
+/**
+ * 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, false);
+}
+/**
+ * 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) {
+ if (string == null) error(SWT.ERROR_NULL_ARGUMENT);
+ byte[] buffer = Converter.wcsToMbcs(null, string, true);
+ byte[] buffer1 = Converter.wcsToMbcs(null, "Y", true);
+ int fontHandle = _getGCFont();
+ int[] unused = new int[1];
+ int[] width = new int[1];
+ int[] ascent = new int[1];
+ int[] average_ascent = new int [1];
+ OS.gdk_string_extents(fontHandle, buffer, unused, unused, width, ascent, unused);
+ OS.gdk_string_extents(fontHandle, buffer1, unused, unused, unused, average_ascent, unused);
+ if (ascent[0]<average_ascent[0]) ascent[0] = average_ascent[0];
+ if (!isTransparent) {
+ int height = OS.gdk_string_height(fontHandle, buffer);
+ GdkGCValues values = new GdkGCValues();
+ OS.gdk_gc_get_values(handle, values);
+ GdkColor color = new GdkColor();
+ color.pixel = values.background_pixel;
+ color.red = values.background_red;
+ color.green = values.background_green;
+ color.blue = values.background_blue;
+ OS.gdk_gc_set_foreground(handle, color);
+ OS.gdk_draw_rectangle(data.drawable, handle, 1, x, y, width[0], height);
+ color.pixel = values.foreground_pixel;
+ color.red = values.foreground_red;
+ color.green = values.foreground_green;
+ color.blue = values.foreground_blue;
+ OS.gdk_gc_set_foreground(handle, color);
+ }
+ OS.gdk_draw_string(data.drawable, fontHandle, handle, x, y + ascent[0], buffer);
+}
+
+/**
+ * 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 specifing 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) {
+ // NOT IMPLEMENTED
+ drawText(string, x, y, (flags & SWT.DRAW_TRANSPARENT) != 0);
+}
+
+/**
+ * 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 IllegalArgumentException <ul>
+ * <li>ERROR_INVALID_ARGUMENT - if any of the width, height or endAngle is zero.</li>
+ * </ul>
+ * @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 endAngle) {
+ if (width < 0) {
+ x = x + width;
+ width = -width;
+ }
+ if (height < 0) {
+ y = y + height;
+ height = -height;
+ }
+ if (width == 0 || height == 0 || endAngle == 0) {
+ error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ GdkGCValues values = new GdkGCValues();
+ OS.gdk_gc_get_values(handle, values);
+ GdkColor color = new GdkColor();
+ color.pixel = values.background_pixel;
+ color.red = values.background_red;
+ color.green = values.background_green;
+ color.blue = values.background_blue;
+ OS.gdk_gc_set_foreground(handle, color);
+ OS.gdk_draw_arc(data.drawable, handle, 1, x, y, width, height, startAngle * 64, endAngle * 64);
+ color.pixel = values.foreground_pixel;
+ color.red = values.foreground_red;
+ color.green = values.foreground_green;
+ color.blue = values.foreground_blue;
+ OS.gdk_gc_set_foreground(handle, color);
+}
+
+/**
+ * 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
+ */
+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;
+
+ GdkGCValues values = new GdkGCValues();
+ OS.gdk_gc_get_values(handle, values);
+ GdkColor foregroundGdkColor = new GdkColor();
+
+ RGB backgroundRGB, foregroundRGB;
+ backgroundRGB = Color.gtk_getRGBIntensities(_getBackgroundGdkColor());
+ foregroundRGB = Color.gtk_getRGBIntensities(_getForegroundGdkColor());
+
+ 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 == toRGB) {
+ fillRectangle(x, y, width, height);
+ return;
+ }
+ ImageData.fillGradientRectangle(this, Display.getCurrent(),
+ x, y, width, height, vertical, fromRGB, toRGB,
+ 8, 8, 8);
+}
+
+/**
+ * Fills the interior of an oval, within the specified
+ * rectangular area, with the receiver's background
+ * color.
+ *
+ * @param x the x coordinate of the upper left corner of the oval to be filled
+ * @param y the y coordinate of the upper left corner of the oval to be filled
+ * @param width the width of the oval to be filled
+ * @param height the height of the oval to be filled
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see #drawOval
+ */
+public void fillOval(int x, int y, int width, int height) {
+ if (width < 0) {
+ x = x + width;
+ width = -width;
+ }
+ if (height < 0) {
+ y = y + height;
+ height = -height;
+ }
+ GdkGCValues values = new GdkGCValues();
+ OS.gdk_gc_get_values(handle, values);
+ GdkColor color = new GdkColor();
+ color.pixel = values.background_pixel;
+ color.red = values.background_red;
+ color.green = values.background_green;
+ color.blue = values.background_blue;
+ OS.gdk_gc_set_foreground(handle, color);
+ OS.gdk_draw_arc(data.drawable, handle, 1, x, y, width, height, 0, 23040);
+ color.pixel = values.foreground_pixel;
+ color.red = values.foreground_red;
+ color.green = values.foreground_green;
+ color.blue = values.foreground_blue;
+ OS.gdk_gc_set_foreground(handle, color);
+}
+/**
+ * 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 (pointArray == null) error(SWT.ERROR_NULL_ARGUMENT);
+ short[] points = new short[pointArray.length];
+ for (int i = 0; i < pointArray.length; i++) {
+ points[i] = (short)pointArray[i];
+ }
+ GdkGCValues values = new GdkGCValues();
+ OS.gdk_gc_get_values(handle, values);
+ GdkColor color = new GdkColor();
+ color.pixel = values.background_pixel;
+ color.red = values.background_red;
+ color.green = values.background_green;
+ color.blue = values.background_blue;
+ OS.gdk_gc_set_foreground(handle, color);
+ OS.gdk_draw_polygon(data.drawable, handle, 1, points, points.length / 2);
+ color.pixel = values.foreground_pixel;
+ color.red = values.foreground_red;
+ color.green = values.foreground_green;
+ color.blue = values.foreground_blue;
+ OS.gdk_gc_set_foreground(handle, color);
+}
+/**
+ * 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
+ */
+public void fillRectangle(int x, int y, int width, int height) {
+ if (width < 0) {
+ x = x + width;
+ width = -width;
+ }
+ if (height < 0) {
+ y = y + height;
+ height = -height;
+ }
+
+ GdkGCValues values = new GdkGCValues();
+ OS.gdk_gc_get_values(handle, values);
+ GdkColor color = new GdkColor();
+ color.pixel = values.background_pixel;
+ color.red = values.background_red;
+ color.green = values.background_green;
+ color.blue = values.background_blue;
+ OS.gdk_gc_set_foreground(handle, color);
+ OS.gdk_draw_rectangle(data.drawable, handle, 1, x, y, width, height);
+ color.pixel = values.foreground_pixel;
+ color.red = values.foreground_red;
+ color.green = values.foreground_green;
+ color.blue = values.foreground_blue;
+ OS.gdk_gc_set_foreground(handle, color);
+}
+/**
+ * Fills the interior of the specified rectangle, using the receiver's
+ * background color.
+ *
+ * @param rectangle 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
+ */
+public void fillRectangle(Rectangle rect) {
+ if (rect == null) 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 horizontal diameter of the arc at the four corners
+ * @param arcHeight the vertical diameter of the arc at the four corners
+ *
+ * @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) {
+ 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;
+
+ naw = Math.min(naw,nw);
+ nah = Math.min(nah, nh);
+
+ int naw2 = Compatibility.round(naw, 2);
+ int nah2 = Compatibility.round(nah, 2);
+
+ GdkGCValues values = new GdkGCValues();
+ OS.gdk_gc_get_values(handle, values);
+ GdkColor color = new GdkColor();
+ color.pixel = values.background_pixel;
+ color.red = values.background_red;
+ color.green = values.background_green;
+ color.blue = values.background_blue;
+ OS.gdk_gc_set_foreground(handle, color);
+ OS.gdk_draw_arc(data.drawable, handle, 1, nx, ny, naw, nah, 5760, 5760);
+ OS.gdk_draw_arc(data.drawable, handle, 1, nx, ny + nh - nah, naw, nah, 11520, 5760);
+ OS.gdk_draw_arc(data.drawable, handle, 1, nx + nw - naw, ny + nh - nah, naw, nah, 17280, 5760);
+ OS.gdk_draw_arc(data.drawable, handle, 1, nx + nw - naw, ny, naw, nah, 0, 5760);
+ OS.gdk_draw_rectangle(data.drawable, handle, 1, nx + naw2, ny, nw - naw, nh);
+ OS.gdk_draw_rectangle(data.drawable, handle, 1, nx, ny + nah2, naw2, nh - nah);
+ OS.gdk_draw_rectangle(data.drawable, handle, 1, nx + nw - (naw / 2), ny + nah2, naw2, nh -nah);
+ color.pixel = values.foreground_pixel;
+ color.red = values.foreground_red;
+ color.green = values.foreground_green;
+ color.blue = values.foreground_blue;
+ OS.gdk_gc_set_foreground(handle, color);
+}
+
+/**
+ * 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
+ */
+/*
+ * === As yet unclassified ===
+ */
+
+public boolean equals(Object object) {
+ return (object == this) || ((object instanceof GC) && (handle == ((GC)object).handle));
+}
+/**
+ * Returns an integer hash code for the receiver. Any two
+ * objects which return <code>true</code> when passed to
+ * <code>equals</code> must return the same value for this
+ * method.
+ *
+ * @return the receiver's hash
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see #equals
+ */
+public int hashCode() {
+ return handle;
+}
+void error(int code) {
+ throw new SWTError(code);
+}
+/**
+ * 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;
+}
+/**
+ * Disposes of the operating system resources associated with
+ * the graphics context. Applications must dispose of all GCs
+ * which they allocate.
+ */
+public void dispose() {
+ if (handle == 0) return;
+
+ /* Free resources */
+ int clipRgn = data.clipRgn;
+ if (clipRgn != 0) OS.gdk_region_destroy(clipRgn);
+ Image image = data.image;
+ if (image != null) image.memGC = null;
+
+ /* Dispose the GC */
+ if(drawable == null)
+ OS.gdk_gc_unref(handle);
+ else
+ drawable.internal_dispose_GC(handle, data);
+
+ data.drawable = // data.colormap = data.fontList =
+ data.clipRgn = data.renderTable = 0;
+ drawable = null;
+ data.image = null;
+ data = null;
+ handle = 0;
+
+}
+
+/**
+ * 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 specifing 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) {
+ //NOT IMPLEMENTED
+ return textExtent(string);
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GCData.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GCData.java
new file mode 100644
index 0000000000..0b3a70386b
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GCData.java
@@ -0,0 +1,28 @@
+package org.eclipse.swt.graphics;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+
+import org.eclipse.swt.*;
+
+/**
+ * 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>
+ *
+ * @private
+ */
+public class GCData {
+ public Image image;
+ public int drawable;
+ public int clipRgn;
+ public int lineStyle = SWT.LINE_SOLID;
+ public int renderTable;
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java
new file mode 100644
index 0000000000..c8d5f3fdd7
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java
@@ -0,0 +1,638 @@
+package org.eclipse.swt.graphics;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+
+import org.eclipse.swt.internal.gtk.*;
+import org.eclipse.swt.widgets.*;
+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 explicitely 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
+ */
+public final class Image implements Drawable{
+
+ /**
+ * specifies whether the receiver is a bitmap or an icon
+ * (one of <code>SWT.BITMAP</code>, <code>SWT.ICON</code>)
+ */
+ public int type;
+
+ /**
+ * The handle to the OS pixmap resource.
+ * Warning: This field is platform dependent.
+ */
+ public int pixmap;
+
+ /**
+ * The handle to the OS mask resource.
+ * Warning: This field is platform dependent.
+ */
+ public int mask;
+
+ /**
+ * The device where this image was created.
+ */
+ Device device;
+
+ /**
+ * specifies the transparent pixel
+ * (Warning: This field is platform dependent)
+ */
+ int transparentPixel = -1;
+
+ /**
+ * The GC the image is currently selected in.
+ * Warning: This field is platform dependent.
+ */
+ GC memGC;
+
+ /**
+ * The alpha data of the image.
+ * Warning: This field is platform dependent.
+ */
+ byte[] alphaData;
+
+ /**
+ * The global alpha value to be used for every pixel.
+ * Warning: This field is platform dependent.
+ */
+ int alpha = -1;
+
+ /**
+ * Specifies the default scanline padding.
+ * Warning: This field is platform dependent.
+ */
+ static final int DEFAULT_SCANLINE_PAD = 4;
+
+
+
+/*
+ * CONSTRUCTORS
+ */
+
+Image() {
+}
+
+/**
+ * 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>
+ *
+ * @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_INVALID_ARGUMENT - if either the width or height is negative</li>
+ * </ul>
+ */
+public Image(Device display, int width, int height) {
+ init(display, width, height);
+}
+
+/**
+ * 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>IMAGE_COPY</b></dt>
+ * <dd>the result is an identical copy of srcImage</dd>
+ * <dt><b>IMAGE_DISABLE</b></dt>
+ * <dd>the result is a copy of srcImage which has a <em>disabled</em> look</dd>
+ * <dt><b>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 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>
+ * </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) {
+ /* basic sanity */
+ if (device == null) device = Device.getDevice();
+ if (device == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ this.device = device;
+ if (srcImage == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (srcImage.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ this.type = srcImage.type;
+ this.mask = 0;
+
+ /* this is somewhat ugly, because this dilutes the encapsulation
+ * of knowledge about what the cloning operations do (e.g., the
+ * following lines assume graying and disabling don't change alpha)
+ */
+ this.alphaData = srcImage.alphaData;
+ this.alpha = srcImage.alpha;
+ this.transparentPixel = srcImage.transparentPixel;
+ // bogus - are we sure about memGC?
+
+ /* Special case:
+ * If all we want is just a clone of the existing pixmap, it can
+ * be done entirely in the X server, without copying across the net.
+ */
+ if (flag == SWT.IMAGE_COPY) {
+ int[] unused = new int[1];
+ int[] width = new int[1]; int[] height = new int[1];
+ int[] depth = new int[1];
+ OS.gdk_window_get_geometry(pixmap, unused, unused, width, height, depth);
+ pixmap = OS.gdk_pixmap_new (0, width[0], height[0], depth[0]);
+ int gc = OS.gdk_gc_new (pixmap);
+ OS.gdk_draw_pixmap(pixmap, gc, srcImage.pixmap,
+ 0,0,0,0, width[0], height[0]);
+ OS.gdk_gc_destroy(gc);
+ 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);
+ }
+
+ /* we are not quite done yet. Need to copy the maskData */
+ if (srcImage.mask != 0) {
+ /* Generate the mask if necessary. */
+// if (srcImage.transparentPixel != -1) srcImage.createMask();
+ mask = OS.gdk_pixmap_new(0, width[0], height[0], 1);
+ gc = OS.gdk_gc_new(mask);
+ OS.gdk_draw_pixmap(mask, gc, srcImage.mask,
+ 0,0,0,0, width[0], height[0]);
+ OS.gdk_gc_destroy(gc);
+ /* Destroy the image mask if the there is a GC created on the image */
+ if (srcImage.transparentPixel != -1 && srcImage.memGC != null) srcImage.destroyMask();
+ }
+
+
+ return;
+ }
+
+
+
+
+ Pixbuffer pb = new Pixbuffer(srcImage);
+ Pixbuffer pb2 = new Pixbuffer(pb, flag);
+ pb2.toImage(this);
+
+
+}
+
+/**
+ * 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>
+ *
+ * @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 the bounds rectangle is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if either the rectangle's width or height is negative</li>
+ * </ul>
+ */
+public Image(Device display, Rectangle bounds) {
+ if (bounds == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ init(display, bounds.width, bounds.height);
+}
+
+/**
+ * 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 the image data is null</li>
+ * </ul>
+ */
+public Image(Device display, ImageData image) {
+ if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (display == null) display = Display.getDefault();
+ init(display, image);
+}
+
+/**
+ * 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, and the mask image
+ * must have a color depth of 1. Pixel transparency in either image
+ * will be ignored. If either image is an icon to begin with, an
+ * exception is thrown.
+ * <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 either the source or mask is null </li>
+ * <li>ERROR_INVALID_ARGUMENT - if source and mask are different sizes or
+ * if the mask is not monochrome, or if either the source or mask
+ * is already an icon</li>
+ * </ul>
+ */
+public Image(Device display, ImageData source, ImageData mask) {
+ if (source == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (mask == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (display == null) display = Display.getDefault();
+ if (source.width != mask.width || source.height != mask.height) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ if (mask.depth != 1) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ ImageData image;
+ if (source.depth != 1)
+ image = new ImageData(source.width, source.height, source.depth, source.palette, source.scanlinePad, source.data);
+ else {
+ image = source.getTransparencyMask(); //create an imagedata with scanlinepad == 1 and invalid data
+ int[] row = new int[source.width];
+ for (int y = 0; y < source.height; y++) {
+ source.getPixels(0, y, source.width, row, 0);
+ image.setPixels(0, y, source.width, row, 0);
+ }//change source data format from scanlinePad == 4 to scanlinePad == 1;
+
+ }
+ image.type = SWT.ICON;
+ image.maskPad = mask.scanlinePad;
+ image.maskData = mask.data;
+ init(display, image);
+}
+
+/**
+ * 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.
+ * <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>
+ * new Image(device, clazz.getResourceAsStream("file.gif"));
+ * </pre>
+ *
+ * @param device the device on which to create the image
+ * @param stream the input stream to load the image from
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_INVALID_IMAGE - if the image file contains invalid data </li>
+ * <li>ERROR_IO - if an IO error occurs while reading data</li>
+ * </ul>
+ */
+public Image(Device display, InputStream stream) {
+ if (stream == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (display == null) display = Display.getDefault();
+ init(display, new ImageData(stream));
+}
+
+/**
+ * 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 SWTException <ul>
+ * <li>ERROR_INVALID_IMAGE - if the image file contains invalid data </li>
+ * <li>ERROR_IO - if an IO error occurs while reading data</li>
+ * </ul>
+ */
+public Image(Device display, String filename) {
+ if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (display == null) display = Display.getDefault();
+ init(display, new ImageData(filename));
+}
+
+/**
+ * Destroy the receiver's mask if it exists.
+ */
+void destroyMask() {
+ if (mask == 0) return;
+ OS.gdk_bitmap_unref(mask);
+ mask = 0;
+}
+
+/**
+ * Disposes of the operating system resources associated with
+ * the image. Applications must dispose of all images which
+ * they allocate.
+ */
+public void dispose () {
+ if (pixmap != 0) OS.gdk_pixmap_unref(pixmap);
+ if (mask != 0) OS.gdk_pixmap_unref(mask);
+ pixmap = mask = 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) {
+ return (object == this) || ((object instanceof Image) &&
+ (pixmap == ((Image)object).pixmap) &&
+ (mask == ((Image)object).mask));
+}
+
+/**
+ * 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() {
+ return null;
+}
+
+/**
+ * Sets the color to which to map the transparent pixel.
+ * <p>
+ * There are certain uses of <code>Images</code> that do not support
+ * transparency (for example, setting an image into a button or label).
+ * In these cases, it may be desired to simulate transparency by using
+ * the background color of the widget to paint the transparent pixels
+ * of the image. This method specifies the color that will be used in
+ * these cases. For example:
+ * <pre>
+ * Button b = new Button();
+ * image.setBackground(b.getBackground());>
+ * b.setImage(image);
+ * </pre>
+ * </p><p>
+ * The image may be modified by this operation (in effect, the
+ * transparent regions may be filled with the supplied color). Hence
+ * this operation is not reversible and it is not legal to call
+ * this function twice or with a null argument.
+ * </p><p>
+ * This method has no effect if the receiver does not have a transparent
+ * pixel value.
+ * </p>
+ *
+ * @param color the color to use when a transparent pixel is specified
+ *
+ * @exception IllegalArgumentException <ul>
+ * <li>ERROR_NULL_ARGUMENT - if the color is null</li>
+ * <li>ERROR_INVALID_ARGUMENT - if the color has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public void setBackground(Color color) {
+ if (color == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (color.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+}
+
+/**
+ * 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() {
+ int[] unused = new int[1]; int[] width = new int[1]; int[] height = new int[1];
+ OS.gdk_window_get_geometry(pixmap, unused, unused, width, height, unused);
+ return new Rectangle(0, 0, width[0], height[0]);
+
+}
+/**
+ * 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() {
+ return new Pixbuffer(this).getImageData();
+}
+
+public static Image gtk_new(int type, int pixmap, int mask) {
+ Image image = new Image();
+ image.type = type;
+ image.pixmap = pixmap;
+ image.mask = mask;
+ return image;
+}
+/**
+ * Returns an integer hash code for the receiver. Any two
+ * objects which 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 pixmap;
+}
+/**
+ * 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
+ *
+ * @private
+ */
+public int internal_new_GC (GCData data) {
+ if (pixmap == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+ if (data == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
+ if (type != SWT.BITMAP || memGC != null) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+
+ data.image = this;
+ int gc = OS.gdk_gc_new(pixmap);
+ data.drawable = pixmap;
+ return gc;
+}
+/**
+ * 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 handle the platform specific GC handle
+ * @param data the platform specific GC data
+ *
+ * @private
+ */
+public void internal_dispose_GC (int gc, GCData data) {
+ OS.gdk_gc_unref(gc);
+}
+
+void init(Device display, int width, int height) {
+ device = display;
+ GdkVisual visual = new GdkVisual ();
+ OS.memmove(visual, OS.gdk_visual_get_system(), GdkVisual.sizeof);
+ this.pixmap = OS.gdk_pixmap_new(0, width, height, visual.depth);
+ if (pixmap == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+ /* Fill the bitmap with white */
+ GdkColor white = new GdkColor();
+ int colormap = OS.gdk_colormap_get_system();
+ OS.gdk_color_white(colormap, white);
+ int gc = OS.gdk_gc_new(pixmap);
+ OS.gdk_gc_set_foreground(gc, white);
+ OS.gdk_draw_rectangle(pixmap, gc, 1, 0, 0, width, height);
+ OS.gdk_gc_destroy(gc);
+ OS.gdk_colors_free(colormap, new int[] { white.pixel }, 1, 0);
+ this.type = SWT.BITMAP;
+}
+
+void init(Device display, ImageData image) {
+ if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (display == null) display = Display.getCurrent();
+ device = display;
+
+ /*
+ * We don't really care about the real depth of the ImageData we are
+ * given. We stretch everything to 24bpp which is the native GdkPixbuffer
+ * depth. HOWEVER, there is one situation where this is not acceptable,
+ * namely bitmaps (1bpp), because they may be used in contexts that are
+ * sensitive to pixmap depth.
+ */
+ Pixbuffer buff = new Pixbuffer(image);
+ buff.toImage(this);
+ return;
+}
+
+/**
+ * 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 pixmap == 0;
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Pixbuffer.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Pixbuffer.java
new file mode 100644
index 0000000000..460a3bbb6c
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Pixbuffer.java
@@ -0,0 +1,492 @@
+package org.eclipse.swt.graphics;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.internal.gtk.*;
+
+/**
+ * This class is <strong>not</strong> part of the SWT API,
+ * and its existence is not relevant for application programmers.
+ *
+ * Pixbuffer represents local GdkPixbuf images on the client.
+ */
+final class Pixbuffer {
+
+ /* the handle to the OS resource.
+ All state is kept in the OS */
+ int handle;
+
+ /* pointer to the actual pixel array */
+ int data;
+
+ /* whether the alpha data in the pixbuf is due to
+ a transparency mask or an alpha channel */
+ boolean hasMask = false;
+ boolean hasAlpha = false;
+ int constantAlpha = -1;
+ int transparentPixel = -1;
+
+
+ /*
+ * Constructors.
+ * There are three ways to create a Pixbuffer:
+ * pull one from a Drawable, create from ImageData,
+ * or clone an existing Pixbuffer.
+ */
+
+ private Pixbuffer() {}
+
+ /**
+ * Pull a Pixbuffer from an Image living on the X Server
+ * (making this operation expensive).
+ */
+ Pixbuffer (Image src) {
+ if (src == null || src.pixmap == 0) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+
+ // get the geometry
+ int[] unused = new int[1];
+ int[] w = new int[1];
+ int[] h = new int[1];
+ int[] d = new int[1];
+ OS.gdk_window_get_geometry(src.pixmap, unused, unused, w, h, unused);
+ int width = w[0];
+ int height = h[0];
+
+ // create the actual OS resource
+ createHandle(width, height);
+
+ // pull the color data
+ int cmap = OS.gdk_colormap_get_system();
+ GDKPIXBUF.gdk_pixbuf_get_from_drawable(
+ handle,
+ src.pixmap,
+ cmap,
+ 0,0,0,0,
+ width, height);
+
+ // the tricky part is alpha
+ if (src.alphaData != null) fillAlphaFromAlphaBytes(src.alphaData);
+ else if (src.alpha != -1) fillConstantAlpha(src.alpha);
+ else if (src.mask != 0) fillAlphaFromPixmapMask(src.mask);
+ else if (src.transparentPixel != -1) fillAlphaFromTransparentPixel(src.pixmap, src.transparentPixel);
+ else fillOpaque();
+ }
+
+ /**
+ * Create a Pixbuffer from image data.
+ */
+ Pixbuffer (ImageData src) {
+ if (src == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+
+ createHandle(src.width, src.height);
+
+ // populate the pixbuf with data
+ int stride = GDKPIXBUF.gdk_pixbuf_get_rowstride(handle);
+ int dataSize = src.height*stride;
+ byte[] bytes = new byte[dataSize];
+ switch (src.getTransparencyType()) {
+ case SWT.TRANSPARENCY_ALPHA: _blit2platformAlpha(bytes, src, src.width, src.height, stride); break;
+ case SWT.TRANSPARENCY_MASK: _blit2platformMask (bytes, src, src.width, src.height, stride); break;
+ case SWT.TRANSPARENCY_PIXEL: _blit2platformPixel(bytes, src, src.width, src.height, stride); break;
+ case SWT.TRANSPARENCY_NONE: _blit2platformNone (bytes, src, src.width, src.height, stride); break;
+ }
+ OS.memmove(data, bytes, dataSize);
+ }
+
+ /**
+ * Clone an existing Pixbuffer (possibly making it look
+ * grayed out or disabled)
+ */
+ Pixbuffer (Pixbuffer src, int flag) {
+ if (src == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (src.handle==0) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ this.hasAlpha = src.hasAlpha;
+ this.constantAlpha = src.constantAlpha;
+ this.hasMask = src.hasMask;
+
+ /* First, get a copy all our own */
+ handle = GDKPIXBUF.gdk_pixbuf_copy(src.handle);
+ data = GDKPIXBUF.gdk_pixbuf_get_pixels(this.handle);
+
+ // simplest case - just clone what we have
+ if (flag==SWT.IMAGE_COPY) return;
+
+ // gather some information we will need for disabling or graying
+ int width = getWidth();
+ int height = getHeight();
+ int stride = GDKPIXBUF.gdk_pixbuf_get_rowstride(this.handle);
+ int dataSize = height * stride;
+ byte[] bytes = new byte[dataSize];
+ OS.memmove(bytes,data,dataSize);
+ int lineAddress = 0;
+ int pixelAddress;
+
+ if (flag==SWT.IMAGE_DISABLE) {
+ for (int y=0; y<height; y++) {
+ for (int x=0; x<width; x++) {
+ pixelAddress = lineAddress+x*4;
+
+ int intensity =
+ bytes[pixelAddress+0] * bytes[pixelAddress+0] +
+ bytes[pixelAddress+1] * bytes[pixelAddress+1] +
+ bytes[pixelAddress+2] * bytes[pixelAddress+2];
+ byte value = (intensity < 9000)?
+ (byte)0 : (byte) 255;
+ bytes[pixelAddress+0] = bytes[pixelAddress+1] = bytes[pixelAddress+2] = value;
+ // no change to alpha
+ }
+ lineAddress += stride;
+ }
+ /* move it back */
+ OS.memmove(data, bytes, dataSize);
+ return;
+ }
+
+ if (flag==SWT.IMAGE_GRAY) {
+ for (int y=0; y<height; y++) {
+ for (int x=0; x<width; x++) {
+ pixelAddress = lineAddress+x*4;
+ int intensity =
+ (bytes[pixelAddress+0] +
+ bytes[pixelAddress+1] +
+ bytes[pixelAddress+2] ) / 3;
+ bytes[pixelAddress+0] = (byte)intensity;
+ bytes[pixelAddress+1] = (byte)intensity;
+ bytes[pixelAddress+2] = (byte)intensity;
+ // no change to alpha
+ }
+ lineAddress += stride;
+ }
+ /* move it back */
+ OS.memmove(data, bytes, dataSize);
+ return;
+ }
+
+ // flag is neither COPY nor DISABLE nor GRAY
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+
+
+ /**
+ * Push the pixbuf to the X Server
+ */
+ void toImage (Image dest) {
+ if (dest==null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ int w = getWidth();
+ int h = getHeight();
+ GdkVisual visual = new GdkVisual();
+ OS.memmove(visual, OS.gdk_visual_get_system(), GdkVisual.sizeof);
+ dest.pixmap = OS.gdk_pixmap_new (0, w, h, visual.depth);
+ dest.mask = 0; // for now; we fill it later in this method
+ GDKPIXBUF.gdk_pixbuf_render_to_drawable_alpha(handle, // src
+ dest.pixmap, // dest drawable
+ 0,0, 0,0,
+ w, h,
+ GDKPIXBUF.GDK_PIXBUF_ALPHA_BILEVEL, 128,
+ GDKPIXBUF.GDK_RGB_DITHER_NORMAL, 0,0);
+
+ // now the mask, if any
+ if (hasMask) {
+ // bring the pixel data into Java memory
+ int stride = GDKPIXBUF.gdk_pixbuf_get_rowstride(handle);
+ byte[] srcBytes = new byte[h*stride];
+ OS.memmove(srcBytes, data, h*stride);
+
+ // the mask lines are padded to 4 bytes, that is 32 pixels
+ int maskwpl = w/32; if (w%32!=0) maskwpl+=1;
+ int maskBpl = maskwpl*4; // Bytes per line for the mask
+ byte[] bytes = new byte[h * maskBpl];
+ for (int y=0; y<h; y++) {
+ int lineAddress = y * maskBpl;
+ for (int x=0; x<w; x++)
+ if (srcBytes[y*stride + x*4 + 3] != 0) {
+ int byteAddress = lineAddress + x/8;
+ int bit = 1<<(x%8);
+ bytes[byteAddress] |= (byte)bit;
+ } // if
+ } // for y
+ dest.mask = OS.gdk_bitmap_create_from_data(0, bytes, maskBpl*8, h);
+ } // hasMask
+
+ else if (hasAlpha) {
+ SWT.error(SWT.ERROR_NOT_IMPLEMENTED);
+ }
+
+ else if (constantAlpha!=-1) {
+ SWT.error(SWT.ERROR_NOT_IMPLEMENTED);
+ }
+ }
+
+ /**
+ * Return the ImageData for the receiver.
+ */
+ ImageData getImageData() {
+ int width = getWidth();
+ int height = getHeight();
+ int stride = GDKPIXBUF.gdk_pixbuf_get_rowstride(handle);
+ byte[] bytes = _getDataBytes();
+ ImageData answer = new ImageData(width, height, 24, new PaletteData(0xFF0000, 0x00FF00, 0x0000FF));
+
+ if (hasMask) {
+ answer.maskData = new byte[((width+7)/8)*height];
+ answer.maskPad = 1;
+ }
+
+ for (int y=0; y<height; y++)
+ for (int x=0; x<width; x++) {
+ int address = y*stride + x*4;
+ byte r = bytes[address+0];
+ byte g = bytes[address+1];
+ byte b = bytes[address+2];
+ answer.setPixel(x,y, r<<16+g<<8+b);
+ byte alpha = bytes[address+3];
+ if (hasAlpha) {
+ answer.setAlpha(x,y, alpha);
+ }
+ if (hasMask && (alpha!=0)) {
+ // Find out where to stab the bit
+ int mask_bytes_per_line = (width+7) / 8;
+ int x_inside_line = x / 8;
+ int shift_inside_byte = x - (x_inside_line*8);
+ answer.maskData[x_inside_line + (y*mask_bytes_per_line)] |= (128 >> shift_inside_byte);
+ }
+ }
+ if (constantAlpha!=-1) answer.alpha = constantAlpha;
+ return answer;
+ }
+
+ int getWidth() {
+ return GDKPIXBUF.gdk_pixbuf_get_width (handle);
+ }
+
+ int getHeight() {
+ return GDKPIXBUF.gdk_pixbuf_get_height (handle);
+ }
+
+
+ /**
+ * Actually create the OS resource.
+ * No matter what, the GdkPixbuf we create always has
+ * an alpha channel.
+ */
+ private void createHandle(int width, int height) {
+ handle = GDKPIXBUF.gdk_pixbuf_new(GDKPIXBUF.GDK_COLORSPACE_RGB,
+ true,
+ 8,
+ width, height);
+ if (this.handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+ data = GDKPIXBUF.gdk_pixbuf_get_pixels(handle);
+ }
+
+ private void fillAlphaFromPixmapMask(int mask) {
+ hasMask = true;
+
+ /* pull the mask data from the X Server */
+ // get the geometry
+ int[] unused = new int[1];
+ int[] w = new int[1];
+ int[] h = new int[1];
+ int[] d = new int[1];
+ OS.gdk_window_get_geometry(mask, unused, unused, w, h, unused);
+ int width = Math.min(w[0], getWidth());
+ int height = Math.min(h[0], getHeight());
+ /* Get the data */
+ int xMaskPtr = OS.gdk_image_get(mask, 0, 0, width, height);
+ if (xMaskPtr == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+
+ /* stuff the alpha values */
+ byte[] bytes = _getDataBytes();
+ int stride = GDKPIXBUF.gdk_pixbuf_get_rowstride(handle);
+ for (int y=0; y<height; y++)
+ for (int x=0; x<width; x++) {
+ int pixel_value = OS.gdk_image_get_pixel(xMaskPtr, x, y);
+ if (pixel_value==0) bytes[y*stride + x*4 +3] = 0;
+ else if (pixel_value==1) bytes[y*stride + x*4 +3] = (byte)255;
+ else { System.out.println("GDK insanity: bitmap contains bits other than 0 or 1"); SWT.error(SWT.ERROR_UNSPECIFIED); }
+ }
+ /* move it back */
+ OS.memmove(data, bytes, bytes.length);
+ }
+
+ private void fillAlphaFromTransparentPixel(int pm, int pixel) {
+ transparentPixel = pixel;
+
+ /* pull the data from the X Server */
+ // get the geometry
+ int[] unused = new int[1];
+ int[] w = new int[1];
+ int[] h = new int[1];
+ int[] d = new int[1];
+ OS.gdk_window_get_geometry(pm, unused, unused, w, h, unused);
+ int width = Math.min(w[0], getWidth());
+ int height = Math.min(h[0], getHeight());
+ /* Get the data */
+ int xImage = OS.gdk_image_get(pm, 0, 0, width, height);
+ if (xImage == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+
+ /* stuff the alpha values */
+ byte[] bytes = _getDataBytes();
+ int stride = GDKPIXBUF.gdk_pixbuf_get_rowstride(handle);
+ for (int y=0; y<height; y++)
+ for (int x=0; x<width; x++) {
+ int pixel_value = OS.gdk_image_get_pixel(xImage, x, y);
+ if (pixel_value==pixel) bytes[y*stride + x*4 +3] = 0;
+ else bytes[y*stride + x*4 +3] = (byte)255;
+ }
+ /* move it back */
+ OS.memmove(data, bytes, bytes.length);
+ }
+
+ private void fillAlphaFromAlphaBytes(byte[] alpha) {
+ hasAlpha = true;
+ SWT.error (SWT.ERROR_NOT_IMPLEMENTED);
+ }
+
+ private void fillConstantAlpha(int alpha) {
+ if ((alpha<0)||(alpha>255)) SWT.error (SWT.ERROR_INVALID_ARGUMENT);
+ constantAlpha = alpha;
+ _fillConstantAlpha((byte)alpha);
+ }
+
+ private void fillOpaque() {
+ _fillConstantAlpha((byte)255);
+ }
+
+ /**
+ * Assume the handle represents a valid GdkPixbuf,
+ * and data is pointing to the correct location in memory.
+ * Fill all alpha bytes with the specified value.
+ */
+ private void _fillConstantAlpha (byte value) {
+ // first, get some technical info
+ int width = getWidth();
+ int height = getHeight();
+ int stride = GDKPIXBUF.gdk_pixbuf_get_rowstride(this.handle);
+ int dataSize = height * stride;
+ byte[] bytes = new byte[dataSize];
+ OS.memmove(bytes,data,dataSize);
+ int lineAddress = 0;
+ int pixelAddress;
+
+ // set all alpha bytes to 255
+ for (int y=0; y<height; y++) {
+ for (int x=0; x<width; x++) {
+ pixelAddress = lineAddress+x*4;
+ bytes[pixelAddress+3] = value;
+ }
+ lineAddress += stride;
+ }
+ /* move it back */
+ OS.memmove(data, bytes, dataSize);
+ }
+
+ private void _blit2platformNone (byte[] bytes,
+ ImageData source,
+ int width,
+ int height,
+ int stride)
+ {
+ int lineAddress = 0;
+ for (int y=0; y<height; y++) {
+ for (int x=0; x<width; x++) {
+ RGB rgb = source.palette.getRGB(source.getPixel(x,y));
+ bytes[lineAddress + x*4 + 0] = (byte)rgb.red;
+ bytes[lineAddress + x*4 + 1] = (byte)rgb.green;
+ bytes[lineAddress + x*4 + 2] = (byte)rgb.blue;
+ bytes[lineAddress + x*4 + 3] = (byte)255;
+ }
+ lineAddress += stride;
+ }
+ }
+
+ private void _blit2platformAlpha (byte[] bytes,
+ ImageData source,
+ int width,
+ int height,
+ int stride)
+ {
+ hasAlpha = true;
+ int lineAddress = 0;
+ for (int y=0; y<height; y++) {
+ for (int x=0; x<width; x++) {
+ RGB rgb = source.palette.getRGB(source.getPixel(x,y));
+ bytes[lineAddress + x*4 + 0] = (byte)rgb.red;
+ bytes[lineAddress + x*4 + 1] = (byte)rgb.green;
+ bytes[lineAddress + x*4 + 2] = (byte)rgb.blue;
+ bytes[lineAddress + x*4 + 3] = (byte)source.getAlpha(x,y);
+ }
+ lineAddress += stride;
+ }
+ }
+
+ private void _blit2platformPixel (byte[] bytes,
+ ImageData source,
+ int width,
+ int height,
+ int stride
+ )
+ {
+ hasMask = true;
+ int lineAddress = 0;
+ for (int y=0; y<height; y++) {
+ for (int x=0; x<width; x++) {
+ int pixel = source.getPixel(x,y);
+ if (pixel==source.transparentPixel) {
+ bytes[lineAddress + x*4 + 0] = (byte)0;
+ bytes[lineAddress + x*4 + 1] = (byte)0;
+ bytes[lineAddress + x*4 + 2] = (byte)0;
+ bytes[lineAddress + x*4 + 3] = (byte)0;
+ } else {
+ RGB rgb = source.palette.getRGB(pixel);
+ bytes[lineAddress + x*4 + 0] = (byte)rgb.red;
+ bytes[lineAddress + x*4 + 1] = (byte)rgb.green;
+ bytes[lineAddress + x*4 + 2] = (byte)rgb.blue;
+ bytes[lineAddress + x*4 + 3] = (byte)255;
+ }
+ }
+ lineAddress += stride;
+ }
+ }
+
+ private void _blit2platformMask (byte[] bytes,
+ ImageData source,
+ int width,
+ int height,
+ int stride
+ )
+ {
+ hasMask = true;
+ ImageData maskData = source.getTransparencyMask();
+ int lineAddress = 0;
+ for (int y=0; y<height; y++) {
+ for (int x=0; x<width; x++) {
+ RGB rgb = source.palette.getRGB(source.getPixel(x,y));
+ bytes[lineAddress + x*4 + 0] = (byte)rgb.red;
+ bytes[lineAddress + x*4 + 1] = (byte)rgb.green;
+ bytes[lineAddress + x*4 + 2] = (byte)rgb.blue;
+ int alpha = 0;
+ if (maskData.getPixel(x,y) !=0) alpha=255;
+ bytes[lineAddress + x*4 + 3] = (byte)alpha;
+ }
+ lineAddress += stride;
+ }
+ }
+
+ /**
+ * Transfer the pixel data from OS memory to Java memory
+ * and return the Java byte array
+ */
+ private byte[] _getDataBytes() {
+ int height = GDKPIXBUF.gdk_pixbuf_get_height (handle);
+ int stride = GDKPIXBUF.gdk_pixbuf_get_rowstride(handle);
+ int size = height*stride;
+ byte[] bytes = new byte[size];
+ OS.memmove(bytes, data, size);
+ return bytes;
+ }
+}
+
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Region.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Region.java
new file mode 100644
index 0000000000..2b80dd5f8e
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Region.java
@@ -0,0 +1,263 @@
+package org.eclipse.swt.graphics;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved
+ */
+
+import org.eclipse.swt.internal.gtk.*;
+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 rectangles.
+ * <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>
+ */
+public final class Region {
+ /**
+ * the OS resource for the region
+ * (Warning: This field is platform dependent)
+ */
+ public int handle;
+/**
+ * Constructs a new empty region.
+ */
+public Region() {
+ handle = OS.gdk_region_new();
+}
+Region(int handle) {
+ this.handle = handle;
+}
+/**
+ * Adds the given rectangle to the collection of rectangles
+ * 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 (rect == null) error(SWT.ERROR_NULL_ARGUMENT);
+ if (rect.width < 0 || rect.height < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ GdkRectangle gdkRect = new GdkRectangle();
+ gdkRect.x = (short)rect.x;
+ gdkRect.y = (short)rect.y;
+ gdkRect.width = (short)rect.width;
+ gdkRect.height = (short)rect.height;
+ int hOld = handle;
+ /**
+ * Feature in GDK. Due to the way the GDK region calls work,
+ * we have to reassign the handle and destroy the old one.
+ */
+ handle = OS.gdk_region_union_with_rect(handle, gdkRect);
+ OS.gdk_region_destroy(hOld);
+}
+/**
+ * Adds all of the rectangles which make up the area covered
+ * by the argument to the collection of rectangles 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 (region == null) error(SWT.ERROR_NULL_ARGUMENT);
+ /**
+ * Feature in GDK. Due to the way the GDK region calls work,
+ * we have to reassign the handle and destroy the old one.
+ */
+ int hOld = handle;
+ handle = OS.gdk_regions_union(handle, region.handle);
+ OS.gdk_region_destroy(hOld);
+}
+/**
+ * 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) {
+ return OS.gdk_region_point_in(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 (pt == null) error(SWT.ERROR_NULL_ARGUMENT);
+ return contains(pt.x, pt.y);
+}
+/**
+ * Disposes of the operating system resources associated with
+ * the region. Applications must dispose of all regions which
+ * they allocate.
+ */
+public void dispose() {
+ if (handle != 0) OS.gdk_region_destroy(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;
+ int xRegion = ((Region)object).handle;
+ if (handle == xRegion) return true;
+ if (xRegion == 0) return false;
+ return OS.gdk_region_equal(handle, xRegion);
+}
+void error(int code) {
+ throw new SWTError(code);
+}
+/**
+ * Returns a rectangle which represents the rectangular
+ * union of the collection of rectangles 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() {
+ GdkRectangle rect = new GdkRectangle();
+ OS.gdk_region_get_clipbox(handle, rect);
+ return new Rectangle(rect.x, rect.y, rect.width, rect.height);
+}
+public static Region gtk_new(int handle) {
+ return new Region(handle);
+}
+/**
+ * Returns an integer hash code for the receiver. Any two
+ * objects which return <code>true</code> when passed to
+ * <code>equals</code> must return the same value for this
+ * method.
+ *
+ * @return the receiver's hash
+ *
+ * @see #equals
+ */
+public int hashCode() {
+ return handle;
+}
+/**
+ * Returns <code>true</code> if the rectangle described by the
+ * arguments intersects with any of the rectangles the receiver
+ * mainains 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
+ */
+public boolean intersects (int x, int y, int width, int height) {
+ GdkRectangle osRect = new GdkRectangle();
+ osRect.x = (short)x;
+ osRect.y = (short)y;
+ osRect.width = (short)width;
+ osRect.height = (short)height;
+ return OS.gdk_region_rect_in(handle, osRect) != OS.GDK_OVERLAP_RECTANGLE_OUT;
+}
+/**
+ * Returns <code>true</code> if the given rectangle intersects
+ * with any of the rectangles the receiver mainains 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
+ */
+public boolean intersects(Rectangle rect) {
+ if (rect == null) 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() {
+ return OS.gdk_region_empty(handle);
+}
+}

Back to the top