diff options
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics')
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);
+}
+}
|