File eclipse-libswt-cairo1.0-1.patch of Package eclipse

--- cairo/org/eclipse/swt/graphics/Path.java	2005-10-02 00:08:15.000000000 +0200
+++ cairo/org/eclipse/swt/graphics/Path.java	2005-10-02 00:10:44.000000000 +0200
@@ -62,7 +62,10 @@
 	if (device == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
 	this.device = device;
 	device.checkCairo();
-	handle = Cairo.cairo_create();
+	int /*long*/ surface = Cairo.cairo_image_surface_create(Cairo.CAIRO_FORMAT_ARGB32, 1, 1);
+	if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+	handle = Cairo.cairo_create(surface);
+	Cairo.cairo_surface_destroy(surface);
 	if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
 	if (device.tracking) device.new_Object(this);
 }
@@ -99,16 +102,23 @@
 public void addArc(float x, float y, float width, float height, float startAngle, float arcAngle) {
 	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
 	move = true;
-	int /*long*/ matrix = Cairo.cairo_matrix_create();
-	Cairo.cairo_current_matrix(handle, matrix);
-	double lineWidth = Cairo.cairo_current_line_width(handle);
-	Cairo.cairo_translate(handle, x + width / 2f, y + height / 2f);
-	Cairo.cairo_scale(handle, width / 2f, height / 2f);
-	Cairo.cairo_set_line_width(handle, lineWidth / (width / 2f));
-	Cairo.cairo_arc_negative(handle, 0, 0, 1, -startAngle * (float)Compatibility.PI / 180, -(startAngle + arcAngle) * (float)Compatibility.PI / 180);
-	Cairo.cairo_set_line_width(handle, lineWidth);
-	Cairo.cairo_set_matrix(handle, matrix);
-	Cairo.cairo_destroy(matrix);
+	if (width == height) {
+		if (arcAngle >= 0) {
+			Cairo.cairo_arc_negative(handle, x + width / 2f, y + height / 2f, width / 2f, -startAngle * (float)Compatibility.PI / 180, -(startAngle + arcAngle) * (float)Compatibility.PI / 180);
+		} else {
+			Cairo.cairo_arc(handle, x + width / 2f, y + height / 2f, width / 2f, -startAngle * (float)Compatibility.PI / 180, -(startAngle + arcAngle) * (float)Compatibility.PI / 180);
+		}
+	} else {
+		Cairo.cairo_save(handle);
+		Cairo.cairo_translate(handle, x + width / 2f, y + height / 2f);
+		Cairo.cairo_scale(handle, width / 2f, height / 2f);
+		if (arcAngle >= 0) {
+			Cairo.cairo_arc_negative(handle, 0, 0, 1, -startAngle * (float)Compatibility.PI / 180, -(startAngle + arcAngle) * (float)Compatibility.PI / 180);
+		} else {
+			Cairo.cairo_arc(handle, 0, 0, 1, -startAngle * (float)Compatibility.PI / 180, -(startAngle + arcAngle) * (float)Compatibility.PI / 180);
+		}
+		Cairo.cairo_restore(handle);
+	}
 }
 
 /**
@@ -129,7 +139,10 @@
 	if (path == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
 	if (path.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
 	move = false;
-	Cairo.cairo_add_path(handle, path.handle);
+	int /*long*/ copy = Cairo.cairo_copy_path(path.handle);
+	if (copy == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+	Cairo.cairo_append_path(handle, copy);
+	Cairo.cairo_path_destroy(copy);
 }
 
 /**
@@ -174,7 +187,7 @@
 	move = false;
 	GC.setCairoFont(handle, font);
 	cairo_font_extents_t extents = new cairo_font_extents_t();
-	Cairo.cairo_current_font_extents(handle, extents);
+	Cairo.cairo_font_extents(handle, extents);
 	double baseline = y + extents.ascent;
 	Cairo.cairo_move_to(handle, x, baseline);
 	byte[] buffer = Converter.wcsToMbcs(null, string, true);
@@ -227,7 +240,10 @@
 	gc.initCairo();
 	boolean result = false;
 	int /*long*/ cairo = gc.data.cairo;
-	Cairo.cairo_add_path(cairo, handle);
+	int /*long*/ copy = Cairo.cairo_copy_path(handle);
+	if (copy == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+	Cairo.cairo_append_path(cairo, copy);
+	Cairo.cairo_path_destroy(copy);
 	if (outline) {
 		result = Cairo.cairo_in_stroke(cairo, x, y) != 0;		
 	} else {
@@ -255,7 +271,7 @@
 	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
 	if (!move) {
 		double[] currentX = new double[1], currentY = new double[1];
-		Cairo.cairo_current_point(handle, currentX, currentY);
+		Cairo.cairo_get_current_point(handle, currentX, currentY);
 		Cairo.cairo_move_to(handle, currentX[0], currentY[0]);
 	}
 	move = true;
@@ -281,12 +297,58 @@
 	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
 	if (bounds == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
 	if (bounds.length < 4) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
-	double[] extents = new double[4];
-	Cairo.cairo_extents(handle, extents);
-	bounds[0] = (float)extents[0];
-	bounds[1] = (float)extents[1];
-	bounds[2] = (float)(extents[2] - extents[0]);
-	bounds[3] = (float)(extents[3] - extents[1]);
+	int /*long*/ copy = Cairo.cairo_copy_path(handle);
+	if (copy == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+	cairo_path_t path = new cairo_path_t();
+	Cairo.memmove(path, copy, cairo_path_t.sizeof);
+	double minX = 0, minY = 0, maxX = 0, maxY = 0;
+	if (path.num_data > 0) {
+		int i = 0;
+		double[] points = new double[6]; 
+		cairo_path_data_t data = new cairo_path_data_t();
+		while (i < path.num_data) {
+			int /*long*/ offset = path.data + i * cairo_path_data_t.sizeof;
+			Cairo.memmove(data, offset, cairo_path_data_t.sizeof);
+			switch (data.type) {
+				case Cairo.CAIRO_PATH_MOVE_TO:
+					Cairo.memmove(points, offset + cairo_path_data_t.sizeof, cairo_path_data_t.sizeof);
+					minX = Math.min(minX, points[0]);
+					minY = Math.min(minY, points[1]);
+					maxX = Math.max(maxX, points[0]);
+					maxY = Math.max(maxY, points[1]);
+					break;
+				case Cairo.CAIRO_PATH_LINE_TO:
+					Cairo.memmove(points, offset + cairo_path_data_t.sizeof, cairo_path_data_t.sizeof);
+					minX = Math.min(minX, points[0]);
+					minY = Math.min(minY, points[1]);
+					maxX = Math.max(maxX, points[0]);
+					maxY = Math.max(maxY, points[1]);
+					break;
+				case Cairo.CAIRO_PATH_CURVE_TO:
+					Cairo.memmove(points, offset + cairo_path_data_t.sizeof, cairo_path_data_t.sizeof * 3);
+					minX = Math.min(minX, points[0]);
+					minY = Math.min(minY, points[1]);
+					maxX = Math.max(maxX, points[0]);
+					maxY = Math.max(maxY, points[1]);
+					minX = Math.min(minX, points[2]);
+					minY = Math.min(minY, points[3]);
+					maxX = Math.max(maxX, points[2]);
+					maxY = Math.max(maxY, points[3]);
+					minX = Math.min(minX, points[4]);
+					minY = Math.min(minY, points[5]);
+					maxX = Math.max(maxX, points[4]);
+					maxY = Math.max(maxY, points[5]);
+					break;
+				case Cairo.CAIRO_PATH_CLOSE_PATH: break;
+			}
+			i += data.length;
+		}
+	}
+	bounds[0] = (float)minX;
+	bounds[1] = (float)minY;
+	bounds[2] = (float)(maxX - minX);
+	bounds[3] = (float)(maxY - minY);
+	Cairo.cairo_path_destroy(copy);
 }
 
 /**
@@ -308,7 +370,7 @@
 	if (point == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
 	if (point.length < 2) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
 	double[] x = new double[1], y = new double[1];
-	Cairo.cairo_current_point(handle, x, y);
+	Cairo.cairo_get_current_point(handle, x, y);
 	point[0] = (float)x[0];
 	point[1] = (float)y[0];
 }
@@ -326,15 +388,64 @@
  */
 public PathData getPathData() {
 	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
-	int[] n_types = new int[1];
-	int[] n_points = new int[1];
-	Cairo.cairo_points(handle, n_types, n_points, null, null);
-	byte[] types = new byte[n_types[0]];
-	float[] points = new float[n_points[0] * 2];
-	Cairo.cairo_points(handle, n_types, n_points, types, points);
+	int /*long*/ copy = Cairo.cairo_copy_path(handle);
+	if (copy == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+	cairo_path_t path = new cairo_path_t();
+	Cairo.memmove(path, copy, cairo_path_t.sizeof);
+	byte[] types = new byte[path.num_data];
+	float[] pts = new float[path.num_data * 6];
+	int typeIndex = 0, ptsIndex = 0;
+	if (path.num_data > 0) {
+		int i = 0;
+		double[] points = new double[6]; 
+		cairo_path_data_t data = new cairo_path_data_t();
+		while (i < path.num_data) {
+			int /*long*/ offset = path.data + i * cairo_path_data_t.sizeof;
+			Cairo.memmove(data, offset, cairo_path_data_t.sizeof);
+			switch (data.type) {
+				case Cairo.CAIRO_PATH_MOVE_TO:
+					types[typeIndex++] = SWT.PATH_MOVE_TO;
+					Cairo.memmove(points, offset + cairo_path_data_t.sizeof, cairo_path_data_t.sizeof);
+					pts[ptsIndex++] = (float)points[0];
+					pts[ptsIndex++] = (float)points[1];
+					break;
+				case Cairo.CAIRO_PATH_LINE_TO:
+					types[typeIndex++] = SWT.PATH_LINE_TO;
+					Cairo.memmove(points, offset + cairo_path_data_t.sizeof, cairo_path_data_t.sizeof);
+					pts[ptsIndex++] = (float)points[0];
+					pts[ptsIndex++] = (float)points[1];
+					break;
+				case Cairo.CAIRO_PATH_CURVE_TO:
+					types[typeIndex++] = SWT.PATH_CUBIC_TO;
+					Cairo.memmove(points, offset + cairo_path_data_t.sizeof, cairo_path_data_t.sizeof * 3);
+					pts[ptsIndex++] = (float)points[0];
+					pts[ptsIndex++] = (float)points[1];
+					pts[ptsIndex++] = (float)points[2];
+					pts[ptsIndex++] = (float)points[3];
+					pts[ptsIndex++] = (float)points[4];
+					pts[ptsIndex++] = (float)points[5];
+					break;
+				case Cairo.CAIRO_PATH_CLOSE_PATH:
+					types[typeIndex++] = SWT.PATH_CLOSE;
+					break;
+			}
+			i += data.length;
+		}
+	}
+	if (typeIndex != types.length) {
+		byte[] newTypes = new byte[typeIndex];
+		System.arraycopy(types, 0, newTypes, 0, typeIndex);
+		types = newTypes;
+	}
+	if (ptsIndex != pts.length) {
+		float[] newPts = new float[ptsIndex];
+		System.arraycopy(pts, 0, newPts, 0, ptsIndex);
+		pts = newPts;
+	}
+	Cairo.cairo_path_destroy(copy);
 	PathData result = new PathData();
 	result.types = types;
-	result.points = points;
+	result.points = pts;
 	return result;
 }
 
@@ -353,7 +464,7 @@
 	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
 	if (!move) {
 		double[] currentX = new double[1], currentY = new double[1];
-		Cairo.cairo_current_point(handle, currentX, currentY);
+		Cairo.cairo_get_current_point(handle, currentX, currentY);
 		Cairo.cairo_move_to(handle, currentX[0], currentY[0]);
 	}
 	move = true;
@@ -400,7 +511,7 @@
 public void quadTo(float cx, float cy, float x, float y) {
 	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
 	double[] currentX = new double[1], currentY = new double[1];
-	Cairo.cairo_current_point(handle, currentX, currentY);
+	Cairo.cairo_get_current_point(handle, currentX, currentY);
 	if (!move) {
 		Cairo.cairo_move_to(handle, currentX[0], currentY[0]);
 	}
--- cairo/org/eclipse/swt/graphics/Pattern.java	2005-10-02 00:08:15.000000000 +0200
+++ cairo/org/eclipse/swt/graphics/Pattern.java	2005-10-02 00:10:44.000000000 +0200
@@ -94,6 +94,9 @@
  * @see #dispose()
  */
 public Pattern(Device device, float x1, float y1, float x2, float y2, Color color1, Color color2) {
+	this(device, x1, y1, x2, y2, color1, 0xFF, color2, 0xFF);
+}
+public Pattern(Device device, float x1, float y1, float x2, float y2, Color color1, int alpha1, Color color2, int alpha2) {
 	if (device == null) device = Device.getDevice();
 	if (device == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
 	if (color1 == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
@@ -104,9 +107,8 @@
 	device.checkCairo();
 	handle = Cairo.cairo_pattern_create_linear(x1, y1, x2, y2);
 	if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
-	//TODO - how about alpha?
-	GC.setCairoPatternColor(handle, 0, color1);
-	GC.setCairoPatternColor(handle, 1, color2);
+	GC.setCairoPatternColor(handle, 0, color1, alpha1);
+	GC.setCairoPatternColor(handle, 1, color2, alpha2);
 	Cairo.cairo_pattern_set_extend(handle, Cairo.CAIRO_EXTEND_REPEAT);
 	if (device.tracking) device.new_Object(this);
 }
--- cairo/org/eclipse/swt/graphics/Transform.java	2005-10-02 00:08:15.000000000 +0200
+++ cairo/org/eclipse/swt/graphics/Transform.java	2005-10-02 00:10:44.000000000 +0200
@@ -36,7 +36,7 @@
 	 * platforms and should never be accessed from application code.
 	 * </p>
 	 */
-	public int /*long*/ handle;
+	public double[] handle;
 	
 /**
  * Constructs a new identity Transform.
@@ -103,9 +103,9 @@
 	if (device == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
 	this.device = device;
 	device.checkCairo();
-	handle = Cairo.cairo_matrix_create();
-	if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
-	Cairo.cairo_matrix_set_affine(handle, m11, m12, m21, m22, dx, dy);
+	handle = new double[6];
+	if (handle == null) SWT.error(SWT.ERROR_NO_HANDLES);
+	Cairo.cairo_matrix_init(handle, m11, m12, m21, m22, dx, dy);
 	if (device.tracking) device.new_Object(this);
 }
 
@@ -121,10 +121,9 @@
  * they allocate.
  */
 public void dispose() {
-	if (handle == 0) return;
+	if (handle == null) return;
 	if (device.isDisposed()) return;
-	Cairo.cairo_matrix_destroy(handle);
-	handle = 0;
+	handle = null;
 	if (device.tracking) device.dispose_Object(this);
 	device = null;
 }
@@ -148,15 +147,12 @@
 	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
 	if (elements == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
 	if (elements.length < 6) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
-	double[] a = new double[1], b = new double[1], c = new double[1], d = new double[1];
-	double[] tx = new double[1], ty = new double[1];
-	Cairo.cairo_matrix_get_affine(handle, a, b, c, d, tx, ty);
-	elements[0] = (float)a[0];
-	elements[1] = (float)b[0];
-	elements[2] = (float)c[0];
-	elements[3] = (float)d[0];
-	elements[4] = (float)tx[0];
-	elements[5] = (float)ty[0];
+	elements[0] = (float)handle[0];
+	elements[1] = (float)handle[1];
+	elements[2] = (float)handle[2];
+	elements[3] = (float)handle[3];
+	elements[4] = (float)handle[4];
+	elements[5] = (float)handle[5];
 }
 
 /**
@@ -186,7 +182,7 @@
  * @return <code>true</code> when the Transform is disposed, and <code>false</code> otherwise
  */
 public boolean isDisposed() {
-	return handle == 0;
+	return handle == null;
 }
 
 /**
@@ -275,7 +271,7 @@
  */
 public void setElements(float m11, float m12, float m21, float m22, float dx, float dy) {
 	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
-	Cairo.cairo_matrix_set_affine(handle, m11, m12, m21, m22, dx, dy);
+	Cairo.cairo_matrix_init(handle, m11, m12, m21, m22, dx, dy);
 }
 
 /** 
--- gtk/org/eclipse/swt/graphics/GCData.java	2005-10-02 00:08:13.000000000 +0200
+++ gtk/org/eclipse/swt/graphics/GCData.java	2005-10-02 00:10:44.000000000 +0200
@@ -41,12 +41,13 @@
 	public int lineStyle = SWT.LINE_SOLID;
 	public int[] dashes;
 	public boolean xorMode;
+	public int alpha = 0xFF;
 	public int antialias = SWT.DEFAULT;
 	public int textAntialias = SWT.DEFAULT;
 	public int interpolation = SWT.DEFAULT;
 
 	public int /*long*/ cairo;
-	public int /*long*/ matrix, inverseMatrix;
+	public double[] matrix, inverseMatrix;
 
 	public String string;
 	public int stringWidth = -1;
--- gtk/org/eclipse/swt/graphics/GC.java	2005-10-02 00:08:13.000000000 +0200
+++ gtk/org/eclipse/swt/graphics/GC.java	2005-10-02 00:10:44.000000000 +0200
@@ -145,6 +145,7 @@
 public static GC gtk_new(Drawable drawable, GCData data) {
 	GC gc = new GC();
 	int /*long*/ gdkGC = drawable.internal_new_GC(data);
+	gc.device = data.device;
 	gc.init(drawable, data, gdkGC);
 	return gc;
 }
@@ -268,11 +269,8 @@
 	
 	int /*long*/ cairo = data.cairo;
 	if (cairo != 0) Cairo.cairo_destroy(cairo);
-	int /*long*/ matrix = data.matrix;
-	if (matrix != 0) Cairo.cairo_matrix_destroy(matrix);
-	int /*long*/ inverseMatrix = data.inverseMatrix;
-	if (inverseMatrix != 0) Cairo.cairo_matrix_destroy(inverseMatrix);
-	data.cairo = data.matrix = data.inverseMatrix = 0;
+	data.cairo = 0;
+	data.matrix = data.inverseMatrix = null;
 
 	/* Free resources */
 	int /*long*/ clipRgn = data.clipRgn;
@@ -344,14 +342,25 @@
 	if (width == 0 || height == 0 || arcAngle == 0) return;
 	int /*long*/ cairo = data.cairo;
 	if (cairo != 0) {
-		Cairo.cairo_save(cairo);
 		float offset = data.lineWidth == 0 || (data.lineWidth % 2) == 1 ? 0.5f : 0f;
-		Cairo.cairo_translate(cairo, x + offset + width / 2f, y + offset + height / 2f);
-		Cairo.cairo_scale(cairo, width / 2f, height / 2f);
-		Cairo.cairo_set_line_width(cairo, Cairo.cairo_current_line_width(cairo) / (width / 2f));
-		Cairo.cairo_arc_negative(cairo, 0, 0, 1, -startAngle * (float)Compatibility.PI / 180, -(startAngle + arcAngle) * (float)Compatibility.PI / 180);
+		if (width == height) {
+            if (arcAngle >= 0) {
+                Cairo.cairo_arc_negative(cairo, x + offset + width / 2f, y + offset + height / 2f, width / 2f, -startAngle * (float)Compatibility.PI / 180, -(startAngle + arcAngle) * (float)Compatibility.PI / 180);
+            } else { 
+                Cairo.cairo_arc(cairo, x + offset + width / 2f, y + offset + height / 2f, width / 2f, -startAngle * (float)Compatibility.PI / 180, -(startAngle + arcAngle) * (float)Compatibility.PI / 180);
+            }
+		} else {
+			Cairo.cairo_save(cairo);
+			Cairo.cairo_translate(cairo, x + offset + width / 2f, y + offset + height / 2f);
+			Cairo.cairo_scale(cairo, width / 2f, height / 2f);
+            if (arcAngle >= 0) {
+                Cairo.cairo_arc_negative(cairo, 0, 0, 1, -startAngle * (float)Compatibility.PI / 180, -(startAngle + arcAngle) * (float)Compatibility.PI / 180);
+            } else {
+                Cairo.cairo_arc(cairo, 0, 0, 1, -startAngle * (float)Compatibility.PI / 180, -(startAngle + arcAngle) * (float)Compatibility.PI / 180);
+            }
+			Cairo.cairo_restore(cairo);
+		}
 		Cairo.cairo_stroke(cairo);
-		Cairo.cairo_restore(cairo);
 		return;
 	}
 	OS.gdk_draw_arc(data.drawable, handle, 0, x, y, width, height, startAngle * 64, arcAngle * 64);
@@ -472,6 +481,39 @@
 			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
 		}
  	}
+	int /*long*/ cairo = data.cairo;
+	if (cairo != 0) {
+		if (data.alpha != 0) {
+			srcImage.createSurface();
+			Cairo.cairo_save(cairo);
+			Cairo.cairo_rectangle(cairo, destX + 0.5, destY + 0.5, destWidth, destHeight);
+			Cairo.cairo_clip(cairo);
+			Cairo.cairo_translate(cairo, destX - srcX + 0.5, destY - srcY + 0.5);
+			if (srcWidth != destWidth || srcHeight != destHeight) {
+				Cairo.cairo_scale(cairo, destWidth / (float)srcWidth,  destHeight / (float)srcHeight);
+			}
+			int filter = Cairo.CAIRO_FILTER_GOOD;
+			switch (data.interpolation) {
+				case SWT.DEFAULT: filter = Cairo.CAIRO_FILTER_GOOD; break;
+				case SWT.NONE: filter = Cairo.CAIRO_FILTER_NEAREST; break;
+				case SWT.LOW: filter = Cairo.CAIRO_FILTER_FAST; break;
+				case SWT.HIGH: filter = Cairo.CAIRO_FILTER_BEST; break;
+			}
+			int /*long*/ pattern = Cairo.cairo_pattern_create_for_surface(srcImage.surface);
+			if (pattern == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+			Cairo.cairo_pattern_set_filter(pattern, filter);
+			Cairo.cairo_pattern_set_extend(pattern, Cairo.CAIRO_EXTEND_REFLECT);
+			Cairo.cairo_set_source(cairo, pattern);
+			if (data.alpha != 0xFF) {
+				Cairo.cairo_paint_with_alpha(cairo, data.alpha / (float)0xFF);
+			} else {
+				Cairo.cairo_paint(cairo);
+			}
+			Cairo.cairo_restore(cairo);
+			Cairo.cairo_pattern_destroy(pattern);
+		}
+		return;
+	}
 	if (srcImage.alpha != -1 || srcImage.alphaData != null) {
 		drawImageAlpha(srcImage, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple, imgWidth, imgHeight);
 	} else if (srcImage.transparentPixel != -1 || srcImage.mask != 0) {
@@ -481,33 +523,6 @@
 	}
 }
 void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple, int imgWidth, int imgHeight) {
-	int /*long*/ cairo = data.cairo;
-	if (cairo != 0) {
-		srcImage.createSurface();
-		Cairo.cairo_save(cairo);
-		//TODO - draw a piece of the image
-//		if (srcX != 0 || srcY != 0) {
-//			Cairo.cairo_rectangle(cairo, destX, destY, destWidth, destHeight);
-//			Cairo.cairo_clip(cairo);
-//			Cairo.cairo_new_path(cairo);
-//		}
-		//TODO - need 0.5 to draw at 0,0 with no transformation ???
-		Cairo.cairo_translate(cairo, destX - srcX + 0.5, destY - srcY);
-		if (srcWidth != destWidth || srcHeight != destHeight) {
-			Cairo.cairo_scale(cairo, destWidth / (float)srcWidth,  destHeight / (float)srcHeight);
-		}
-		int filter = Cairo.CAIRO_FILTER_GOOD;
-		switch (data.interpolation) {
-			case SWT.DEFAULT: filter = Cairo.CAIRO_FILTER_GOOD; break;
-			case SWT.NONE: filter = Cairo.CAIRO_FILTER_NEAREST; break;
-			case SWT.LOW: filter = Cairo.CAIRO_FILTER_FAST; break;
-			case SWT.HIGH: filter = Cairo.CAIRO_FILTER_BEST; break;
-		}
-		Cairo.cairo_surface_set_filter(srcImage.surface, filter);
-		Cairo.cairo_show_surface(cairo, srcImage.surface, imgWidth, imgHeight);
-		Cairo.cairo_restore(cairo);
-		return;
-	}
 	if (srcWidth == destWidth && srcHeight == destHeight) {
 		OS.gdk_draw_drawable(data.drawable, handle, srcImage.pixmap, srcX, srcY, destX, destY, destWidth, destHeight);
 	} else {
@@ -718,14 +733,17 @@
 	}
 	int /*long*/ cairo = data.cairo;
 	if (cairo != 0) {
-		Cairo.cairo_save(cairo);
 		float offset = data.lineWidth == 0 || (data.lineWidth % 2) == 1 ? 0.5f : 0f;
-		Cairo.cairo_translate(cairo, x + offset + width / 2f, y + offset + height / 2f);
-		Cairo.cairo_scale(cairo, width / 2f, height / 2f);
-		Cairo.cairo_set_line_width(cairo, Cairo.cairo_current_line_width(cairo) / (width / 2f));
-		Cairo.cairo_arc_negative(cairo, 0, 0, 1, 0, -2 * (float)Compatibility.PI);
+		if (width == height) {
+			Cairo.cairo_arc_negative(cairo, x + offset + width / 2f, y + offset + height / 2f, width / 2f, 0, -2 * (float)Compatibility.PI);
+		} else {
+			Cairo.cairo_save(cairo);
+			Cairo.cairo_translate(cairo, x + offset + width / 2f, y + offset + height / 2f);
+			Cairo.cairo_scale(cairo, width / 2f, height / 2f);
+			Cairo.cairo_arc_negative(cairo, 0, 0, 1, 0, -2 * (float)Compatibility.PI);
+			Cairo.cairo_restore(cairo);
+		}
 		Cairo.cairo_stroke(cairo);
-		Cairo.cairo_restore(cairo);
 		return;
 	}
 	OS.gdk_draw_arc(data.drawable, handle, 0, x, y, width, height, 0, 23040);
@@ -757,7 +775,10 @@
 	Cairo.cairo_save(cairo);
 	float offset = data.lineWidth == 0 || (data.lineWidth % 2) == 1 ? 0.5f : 0f;
 	Cairo.cairo_translate(cairo, offset, offset);
-	Cairo.cairo_add_path(cairo, path.handle);
+	int /*long*/ copy = Cairo.cairo_copy_path(path.handle);
+	if (copy == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+	Cairo.cairo_append_path(cairo, copy);
+	Cairo.cairo_path_destroy(copy);
 	Cairo.cairo_stroke(cairo);
 	Cairo.cairo_restore(cairo);
 }
@@ -964,13 +985,13 @@
 		Cairo.cairo_translate(cairo, nx + offset, ny + offset);
 		Cairo.cairo_scale(cairo, naw2, nah2);
 		Cairo.cairo_move_to(cairo, fw - 1, 0);
-//		Cairo.cairo_arc_to(cairo, 0, 0, 0, 1, 1);
-//		Cairo.cairo_arc_to(cairo, 0, fh, 1, fh, 1);
-//		Cairo.cairo_arc_to(cairo, fw, fh, fw, fh - 1, 1);
-//		Cairo.cairo_arc_to(cairo, fw, 0, fw - 1, 0, 1);
+	    Cairo.cairo_arc(cairo, fw - 1, 1, 1, Math.PI + Math.PI/2.0, Math.PI*2.0);
+	    Cairo.cairo_arc(cairo, fw - 1, fh - 1, 1, 0, Math.PI/2.0);
+	    Cairo.cairo_arc(cairo, 1, fh - 1, 1, Math.PI/2, Math.PI);
+	    Cairo.cairo_arc(cairo, 1, 1, 1, Math.PI, 270.0*Math.PI/180.0);
 		Cairo.cairo_close_path(cairo);
-		Cairo.cairo_stroke(cairo);
 		Cairo.cairo_restore(cairo);
+		Cairo.cairo_stroke(cairo);
 		return;
 	}
 	int naw2 = naw / 2;
@@ -1139,12 +1160,11 @@
 	if (cairo != 0) {
 		//TODO - honor flags
 		cairo_font_extents_t extents = new cairo_font_extents_t();
-		Cairo.cairo_current_font_extents(cairo, extents);
+		Cairo.cairo_font_extents(cairo, extents);
 		double baseline = y + extents.ascent;
 		Cairo.cairo_move_to(cairo, x, baseline);
 		byte[] buffer = Converter.wcsToMbcs(null, string, true);
-		Cairo.cairo_text_path(cairo, buffer);
-		Cairo.cairo_fill(cairo);
+		Cairo.cairo_show_text(cairo, buffer);
 		return;
 	}
 	setString(string, flags);
@@ -1251,18 +1271,32 @@
 	color.pixel = values.background_pixel;
 	int /*long*/ cairo = data.cairo;
 	if (cairo != 0) {
-		int /*long*/ colormap = OS.gdk_colormap_get_system();
-		OS.gdk_colormap_query_color(colormap, color.pixel, color);
+		if (width == height) {
+            if (arcAngle >= 0) {
+            	Cairo.cairo_arc_negative(cairo, x + width / 2f, y + height / 2f, width / 2f, -startAngle * (float)Compatibility.PI / 180,  -(startAngle + arcAngle) * (float)Compatibility.PI / 180);
+            } else {
+            	Cairo.cairo_arc(cairo, x + width / 2f, y + height / 2f, width / 2f, -startAngle * (float)Compatibility.PI / 180,  -(startAngle + arcAngle) * (float)Compatibility.PI / 180);
+            }
+			Cairo.cairo_line_to(cairo, x + width / 2f, y + height / 2f);
+		} else {
+			Cairo.cairo_save(cairo);
+			Cairo.cairo_translate(cairo, x + width / 2f, y + height / 2f);
+			Cairo.cairo_scale(cairo, width / 2f, height / 2f);
+			if (arcAngle >= 0) {
+				Cairo.cairo_arc_negative(cairo, 0, 0, 1, -startAngle * (float)Compatibility.PI / 180,  -(startAngle + arcAngle) * (float)Compatibility.PI / 180);
+			} else {
+				Cairo.cairo_arc(cairo, 0, 0, 1, -startAngle * (float)Compatibility.PI / 180,  -(startAngle + arcAngle) * (float)Compatibility.PI / 180);
+			}
+			Cairo.cairo_line_to(cairo, 0, 0);
+			Cairo.cairo_restore(cairo);
+		}
 		Cairo.cairo_save(cairo);
 		if (data.backgroundPattern != null) {
-			Cairo.cairo_set_pattern(cairo, data.backgroundPattern.handle);
+			Cairo.cairo_set_source(cairo, data.backgroundPattern.handle);
 		} else {
-			Cairo.cairo_set_rgb_color(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF);
+			OS.gdk_colormap_query_color(OS.gdk_colormap_get_system(), color.pixel, color);
+			Cairo.cairo_set_source_rgba(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF, data.alpha / (float)0xFF);
 		}
-		Cairo.cairo_translate(cairo, x + width / 2f, y + height / 2f);
-		Cairo.cairo_scale(cairo, width / 2f, height / 2f);
-		Cairo.cairo_arc_negative(cairo, 0, 0, 1, -startAngle * (float)Compatibility.PI / 180,  -(startAngle + arcAngle) * (float)Compatibility.PI / 180);
-		Cairo.cairo_line_to(cairo, 0, 0);
 		Cairo.cairo_fill(cairo);
 		Cairo.cairo_restore(cairo);
 		return;
@@ -1334,13 +1368,13 @@
 		} else {
 			pattern = Cairo.cairo_pattern_create_linear (0.0, 0.0, 1.0, 0.0);
 		}
-		Cairo.cairo_pattern_add_color_stop (pattern, 0, fromRGB.red / 255f, fromRGB.green / 255f, fromRGB.blue / 255f, 1);
-		Cairo.cairo_pattern_add_color_stop (pattern, 1, toRGB.red / 255f, toRGB.green / 255f, toRGB.blue / 255f, 1);
+		Cairo.cairo_pattern_add_color_stop_rgba (pattern, 0, fromRGB.red / 255f, fromRGB.green / 255f, fromRGB.blue / 255f, 1);
+		Cairo.cairo_pattern_add_color_stop_rgba (pattern, 1, toRGB.red / 255f, toRGB.green / 255f, toRGB.blue / 255f, 1);
 		Cairo.cairo_save(cairo);
 		Cairo.cairo_translate(cairo, x, y);
 		Cairo.cairo_scale(cairo, width, height);
 		Cairo.cairo_rectangle(cairo, 0, 0, 1, 1);
-		Cairo.cairo_set_pattern(cairo, pattern);
+		Cairo.cairo_set_source(cairo, pattern);
 		Cairo.cairo_fill(cairo);
 		Cairo.cairo_restore(cairo);
 		Cairo.cairo_pattern_destroy(pattern);
@@ -1383,17 +1417,22 @@
 	color.pixel = values.background_pixel;
 	int /*long*/ cairo = data.cairo;
 	if (cairo != 0) {
-		int /*long*/ colormap = OS.gdk_colormap_get_system();
-		OS.gdk_colormap_query_color(colormap, color.pixel, color);
+		if (width == height) {
+			Cairo.cairo_arc_negative(cairo, x + width / 2f, y + height / 2f, width / 2f, 0, 2 * (float)Compatibility.PI);
+		} else {
+			Cairo.cairo_save(cairo);
+			Cairo.cairo_translate(cairo, x + width / 2f, y + height / 2f);
+			Cairo.cairo_scale(cairo, width / 2f, height / 2f);
+			Cairo.cairo_arc_negative(cairo, 0, 0, 1, 0, 2 * (float)Compatibility.PI);
+			Cairo.cairo_restore(cairo);
+		}
 		Cairo.cairo_save(cairo);
 		if (data.backgroundPattern != null) {
-			Cairo.cairo_set_pattern(cairo, data.backgroundPattern.handle);
+			Cairo.cairo_set_source(cairo, data.backgroundPattern.handle);
 		} else {
-			Cairo.cairo_set_rgb_color(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF);
+			OS.gdk_colormap_query_color(OS.gdk_colormap_get_system(), color.pixel, color);
+			Cairo.cairo_set_source_rgba(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF, data.alpha / (float)0xFF);
 		}
-		Cairo.cairo_translate(cairo, x + width / 2f, y + height / 2f);
-		Cairo.cairo_scale(cairo, width / 2f, height / 2f);
-		Cairo.cairo_arc_negative(cairo, 0, 0, 1, 0, 2 * (float)Compatibility.PI);
 		Cairo.cairo_fill(cairo);
 		Cairo.cairo_restore(cairo);
 		return;
@@ -1435,11 +1474,14 @@
 	OS.gdk_colormap_query_color(colormap, color.pixel, color);
 	Cairo.cairo_save(cairo);
 	if (data.backgroundPattern != null) {
-		Cairo.cairo_set_pattern(cairo, data.backgroundPattern.handle);
+		Cairo.cairo_set_source(cairo, data.backgroundPattern.handle);
 	} else {
-		Cairo.cairo_set_rgb_color(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF);
+		Cairo.cairo_set_source_rgba(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF, data.alpha / (float)0xFF);
 	}
-	Cairo.cairo_add_path(cairo, path.handle);
+	int /*long*/ copy = Cairo.cairo_copy_path(path.handle);
+	if (copy == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+	Cairo.cairo_append_path(cairo, copy);
+	Cairo.cairo_path_destroy(copy);
 	Cairo.cairo_fill(cairo);
 	Cairo.cairo_restore(cairo);
 }
@@ -1476,9 +1518,9 @@
 		OS.gdk_colormap_query_color(colormap, color.pixel, color);
 		Cairo.cairo_save(cairo);
 		if (data.backgroundPattern != null) {
-			Cairo.cairo_set_pattern(cairo, data.backgroundPattern.handle);
+			Cairo.cairo_set_source(cairo, data.backgroundPattern.handle);
 		} else {
-			Cairo.cairo_set_rgb_color(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF);
+			Cairo.cairo_set_source_rgba(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF, data.alpha / (float)0xFF);
 		}
 		drawPolyline(cairo, pointArray, true);
 		Cairo.cairo_fill(cairo);
@@ -1526,9 +1568,9 @@
 		OS.gdk_colormap_query_color(colormap, color.pixel, color);
 		Cairo.cairo_save(cairo);
 		if (data.backgroundPattern != null) {
-			Cairo.cairo_set_pattern(cairo, data.backgroundPattern.handle);
+			Cairo.cairo_set_source(cairo, data.backgroundPattern.handle);
 		} else {
-			Cairo.cairo_set_rgb_color(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF);
+			Cairo.cairo_set_source_rgba(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF, data.alpha / (float)0xFF);
 		}
 		Cairo.cairo_rectangle(cairo, x, y, width, height);
 		Cairo.cairo_fill(cairo);
@@ -1610,20 +1652,22 @@
 		int /*long*/ colormap = OS.gdk_colormap_get_system();
 		OS.gdk_colormap_query_color(colormap, color.pixel, color);
 		Cairo.cairo_save(cairo);
-		if (data.backgroundPattern != null) {
-			Cairo.cairo_set_pattern(cairo, data.backgroundPattern.handle);
-		} else {
-			Cairo.cairo_set_rgb_color(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF);
-		}
+		Cairo.cairo_save(cairo);
 		Cairo.cairo_translate(cairo, nx, ny);
 		Cairo.cairo_scale(cairo, naw2, nah2);
 		Cairo.cairo_move_to(cairo, fw - 1, 0);
-//		Cairo.cairo_arc_to(cairo, 0, 0, 0, 1, 1);
-//		Cairo.cairo_arc_to(cairo, 0, fh, 1, fh, 1);
-//		Cairo.cairo_arc_to(cairo, fw, fh, fw, fh - 1, 1);
-//		Cairo.cairo_arc_to(cairo, fw, 0, fw - 1, 0, 1);
+	    Cairo.cairo_arc(cairo, fw - 1, 1, 1, Math.PI + Math.PI/2.0, Math.PI*2.0);
+	    Cairo.cairo_arc(cairo, fw - 1, fh - 1, 1, 0, Math.PI/2.0);
+	    Cairo.cairo_arc(cairo, 1, fh - 1, 1, Math.PI/2, Math.PI);
+	    Cairo.cairo_arc(cairo, 1, 1, 1, Math.PI, 270.0*Math.PI/180.0);		
 		Cairo.cairo_close_path(cairo);
-		Cairo.cairo_stroke(cairo);
+		Cairo.cairo_restore(cairo);
+		if (data.backgroundPattern != null) {
+			Cairo.cairo_set_source(cairo, data.backgroundPattern.handle);
+		} else {
+			Cairo.cairo_set_source_rgba(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF, data.alpha / (float)0xFF);
+		}
+		Cairo.cairo_fill(cairo);
 		Cairo.cairo_restore(cairo);
 		return;
 	}
@@ -1736,8 +1780,7 @@
  */
 public int getAlpha() {
 	if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
-	if (data.cairo == 0) return 0xFF;
-	return (int)(Cairo.cairo_current_alpha(data.cairo) * 255);
+	return data.alpha;
 }
 
 /**
@@ -1758,8 +1801,15 @@
  */
 public int getAntialias() {
 	if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
-    if (data.cairo != 0) return SWT.ON;
-	return data.antialias;
+    if (data.cairo == 0) return SWT.DEFAULT;
+    int antialias = Cairo.cairo_get_antialias(data.cairo);
+	switch (antialias) {
+		case Cairo.CAIRO_ANTIALIAS_DEFAULT: return SWT.DEFAULT;
+		case Cairo.CAIRO_ANTIALIAS_NONE: return SWT.OFF;
+		case Cairo.CAIRO_ANTIALIAS_GRAY:
+		case Cairo.CAIRO_ANTIALIAS_SUBPIXEL: return SWT.ON;
+	}
+	return SWT.DEFAULT;
 }
 
 /** 
@@ -1909,7 +1959,7 @@
 	if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
 	int /*long*/ cairo = data.cairo;
 	if (cairo == 0) return SWT.FILL_EVEN_ODD;
-	return Cairo.cairo_current_fill_rule(cairo) == Cairo.CAIRO_FILL_RULE_WINDING ? SWT.FILL_WINDING : SWT.FILL_EVEN_ODD;
+	return Cairo.cairo_get_fill_rule(cairo) == Cairo.CAIRO_FILL_RULE_WINDING ? SWT.FILL_WINDING : SWT.FILL_EVEN_ODD;
 }
 
 /** 
@@ -2159,7 +2209,18 @@
  */
 public int getTextAntialias() {
     if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
-    return data.textAntialias;
+    if (data.cairo == 0) return SWT.DEFAULT;
+    int /*long*/ options = Cairo.cairo_font_options_create();
+    Cairo.cairo_get_font_options(data.cairo, options);
+    int antialias = Cairo.cairo_font_options_get_antialias(options);
+    Cairo.cairo_font_options_destroy(options);
+	switch (antialias) {
+		case Cairo.CAIRO_ANTIALIAS_DEFAULT: return SWT.DEFAULT;
+		case Cairo.CAIRO_ANTIALIAS_NONE: return SWT.OFF;
+		case Cairo.CAIRO_ANTIALIAS_GRAY:
+		case Cairo.CAIRO_ANTIALIAS_SUBPIXEL: return SWT.ON;
+	}
+	return SWT.DEFAULT;
 }
 
 /** 
@@ -2186,7 +2247,8 @@
 	if (transform.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
 	int /*long*/ cairo = data.cairo;
 	if (cairo != 0) {
-		Cairo.cairo_matrix_copy(transform.handle, data.matrix);
+		double[] matrix = data.matrix;
+		Cairo.cairo_matrix_init(transform.handle, matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
 	} else {
 		transform.setElements(1, 0, 0, 1, 0, 0);
 	}
@@ -2268,27 +2330,32 @@
 	data.device.checkCairo();
 	int /*long*/ cairo = data.cairo;
 	if (cairo != 0) return;
-	data.cairo = cairo = Cairo.cairo_create();
-	if (cairo == 0) SWT.error(SWT.ERROR_NO_HANDLES);
-	data.matrix = Cairo.cairo_matrix_create();
-	if (data.matrix == 0) SWT.error(SWT.ERROR_NO_HANDLES);
-	data.inverseMatrix = Cairo.cairo_matrix_create();
-	if (data.inverseMatrix == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+	data.matrix = new double[]{1, 0, 0, 1, 0, 0};
+	data.inverseMatrix = new double[]{1, 0, 0, 1, 0, 0};
 	int /*long*/ xDisplay = OS.GDK_DISPLAY();
+	int /*long*/ xVisual = OS.gdk_x11_visual_get_xvisual(OS.gdk_visual_get_system());
 	int /*long*/ xDrawable = 0;
 	int translateX = 0, translateY = 0;
+	int /*long*/ drawable = data.drawable;
 	if (data.image != null) {
-		xDrawable = OS.GDK_PIXMAP_XID(data.drawable);
+		xDrawable = OS.GDK_PIXMAP_XID(drawable);
 	} else {
 		int[] x = new int[1], y = new int[1];
 		int /*long*/ [] real_drawable = new int /*long*/ [1];
-		OS.gdk_window_get_internal_paint_info(data.drawable, real_drawable, x, y);
+		OS.gdk_window_get_internal_paint_info(drawable, real_drawable, x, y);
 		xDrawable = OS.gdk_x11_drawable_get_xid(real_drawable[0]);
 		translateX = -x[0];
 		translateY = -y[0];
 	}
-	Cairo.cairo_set_target_drawable(cairo, xDisplay, xDrawable);
-	Cairo.cairo_translate(cairo, translateX, translateY);
+	int[] w = new int[1], h = new int[1];
+	OS.gdk_drawable_get_size(drawable, w, h);
+	int width = w[0], height = h[0];
+	int /*long*/ surface = Cairo.cairo_xlib_surface_create(xDisplay, xDrawable, xVisual, width, height);
+	if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+	Cairo.cairo_surface_set_device_offset(surface, translateX, translateY);
+	data.cairo = cairo = Cairo.cairo_create(surface);
+	Cairo.cairo_surface_destroy(surface);
+	if (cairo == 0) SWT.error(SWT.ERROR_NO_HANDLES);
 	Cairo.cairo_set_fill_rule(cairo, Cairo.CAIRO_FILL_RULE_EVEN_ODD);
 	GdkGCValues values = new GdkGCValues();
 	OS.gdk_gc_get_values(handle, values);
@@ -2296,7 +2363,7 @@
 	color.pixel = values.foreground_pixel;
 	int /*long*/ colormap = OS.gdk_colormap_get_system();
 	OS.gdk_colormap_query_color(colormap, color.pixel, color);
-	Cairo.cairo_set_rgb_color(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF);
+	Cairo.cairo_set_source_rgba(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF, data.alpha / (float)0xFF);
 	Cairo.cairo_set_line_width(cairo, Math.max(1, values.line_width));
 	int cap = Cairo.CAIRO_LINE_CAP_BUTT;
 	switch (values.cap_style) {
@@ -2356,12 +2423,9 @@
 	return handle == 0;
 }
 
-boolean isIdentity(int /*long*/ matrix) {
-	if (matrix == 0) return true;
-	double[] a = new double[1], b = new double[1], c = new double[1];
-	double[] d = new double[1], tx = new double[1], ty = new double[1];			
-	Cairo.cairo_matrix_get_affine(matrix, a, b, c, d, tx, ty);
-	return a[0] == 1 && b[0] == 0 && c[0] == 0 && d[0] == 1 && tx[0] == 0 && ty[0] == 0;
+boolean isIdentity(double[] matrix) {
+	if (matrix == null) return true;
+	return matrix[0] == 1 && matrix[1] == 0 && matrix[2] == 0 && matrix[3] == 1 && matrix[4] == 0 && matrix[5] == 0;
 }
 
 /**
@@ -2416,12 +2480,9 @@
 	} else {
 		int /*long*/ cairo = data.cairo;
 		if (cairo != 0) Cairo.cairo_destroy(cairo);
-		int /*long*/ matrix = data.matrix;
-		if (matrix != 0) Cairo.cairo_matrix_destroy(matrix);
-		int /*long*/ inverseMatrix = data.inverseMatrix;
-		if (inverseMatrix != 0) Cairo.cairo_matrix_destroy(inverseMatrix);
-		data.cairo = data.matrix = data.inverseMatrix = 0;
-		data.antialias = data.textAntialias = data.interpolation = SWT.DEFAULT;
+		data.cairo = 0;
+		data.matrix = data.inverseMatrix = null;
+		data.interpolation = SWT.DEFAULT;
 		data.backgroundPattern = data.foregroundPattern = null;
 		setClipping(0);
 	}
@@ -2442,7 +2503,17 @@
 	if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
 	if (data.cairo == 0 && (alpha & 0xff) == 0xff) return;
 	initCairo();
-	Cairo.cairo_set_alpha(data.cairo, (alpha & 0xff) / 255f);
+	data.alpha = alpha & 0xff;
+	if (data.foregroundPattern == null) {
+		GdkGCValues values = new GdkGCValues();
+		OS.gdk_gc_get_values(handle, values);
+		GdkColor color = new GdkColor();
+		color.pixel = values.foreground_pixel;
+		int /*long*/ colormap = OS.gdk_colormap_get_system();
+		OS.gdk_colormap_query_color(colormap, color.pixel, color);
+		int /*long*/ cairo = data.cairo;
+		Cairo.cairo_set_source_rgba(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF, data.alpha / (float)0xFF);
+	}
 }
 
 /**
@@ -2468,16 +2539,18 @@
 public void setAntialias(int antialias) {
 	if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
 	if (data.cairo == 0 && antialias == SWT.DEFAULT) return;
+	int mode = 0;
 	switch (antialias) {
-		case SWT.DEFAULT: break;
-		case SWT.OFF: break;
-		case SWT.ON:
-            initCairo();
+		case SWT.DEFAULT: mode = Cairo.CAIRO_ANTIALIAS_DEFAULT; break;
+		case SWT.OFF: mode = Cairo.CAIRO_ANTIALIAS_NONE; break;
+		case SWT.ON: mode = Cairo.CAIRO_ANTIALIAS_GRAY;
             break;
 		default:
 			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
 	}
-	data.antialias = antialias;
+    initCairo();
+    int /*long*/ cairo = data.cairo;
+    Cairo.cairo_set_antialias(cairo, mode);
 }
 
 /**
@@ -2545,12 +2618,12 @@
 	if (pangoStyle == OS.PANGO_STYLE_OBLIQUE) slant = Cairo.CAIRO_FONT_SLANT_OBLIQUE;
 	int weight = Cairo.CAIRO_FONT_WEIGHT_NORMAL;
 	if (pangoWeight == OS.PANGO_WEIGHT_BOLD) weight = Cairo.CAIRO_FONT_WEIGHT_BOLD;
-	Cairo.cairo_select_font(cairo, buffer, slant, weight);
-	Cairo.cairo_scale_font(cairo, height);
+	Cairo.cairo_select_font_face(cairo, buffer, slant, weight);
+	Cairo.cairo_set_font_size(cairo, height);
 }
 
 static void setCairoClip(int /*long*/ cairo, int /*long*/ clipRgn) {
-	Cairo.cairo_init_clip(cairo);
+	Cairo.cairo_reset_clip(cairo);
 	if (clipRgn == 0) return;
 	int[] nRects = new int[1];
 	int /*long*/[] rects = new int /*long*/[1];
@@ -2565,9 +2638,13 @@
 	if (rects[0] != 0) OS.g_free(rects[0]);
 }
 
-static void setCairoPatternColor(int /*long*/ pattern, int offset, Color c) {
+static void setCairoPatternColor(int /*long*/ pattern, int offset, Color c, int alpha) {
 	GdkColor color = c.handle;
-	Cairo.cairo_pattern_add_color_stop(pattern, offset, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF, 1);
+	double aa = (alpha & 0xFF) / (double)0xFF;
+	double red = ((color.red & 0xFFFF) / (double)0xFFFF);
+	double green = ((color.green & 0xFFFF) / (double)0xFFFF);
+	double blue = ((color.blue & 0xFFFF) / (double)0xFFFF);
+	Cairo.cairo_pattern_add_color_stop_rgba(pattern, offset, red, green, blue, aa);
 }
 
 void setClipping(int /*long*/ clipRgn) {
@@ -2659,7 +2736,10 @@
 	if (path != null) {
 		initCairo();
 		int /*long*/ cairo = data.cairo;
-		Cairo.cairo_add_path(cairo, path.handle);
+		int /*long*/ copy = Cairo.cairo_copy_path(path.handle);
+		if (copy == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+		Cairo.cairo_append_path(cairo, copy);
+		Cairo.cairo_path_destroy(copy);
 		Cairo.cairo_clip(cairo);
 		Cairo.cairo_new_path(cairo);
 	}
@@ -2793,7 +2873,7 @@
 	int /*long*/ cairo = data.cairo;
 	if (cairo != 0) {
 		GdkColor gdkColor = color.handle;
-		Cairo.cairo_set_rgb_color(cairo, (gdkColor.red & 0xFFFF) / (float)0xFFFF, (gdkColor.green & 0xFFFF) / (float)0xFFFF, (gdkColor.blue & 0xFFFF) / (float)0xFFFF);
+		Cairo.cairo_set_source_rgba(cairo, (gdkColor.red & 0xFFFF) / (float)0xFFFF, (gdkColor.green & 0xFFFF) / (float)0xFFFF, (gdkColor.blue & 0xFFFF) / (float)0xFFFF, data.alpha / (float)0xFF);
 	}
 	data.foregroundPattern = null;
 }
@@ -2821,7 +2901,7 @@
 	initCairo();
 	int /*long*/ cairo = data.cairo;
 	if (pattern != null) {
-		Cairo.cairo_set_pattern(cairo, pattern.handle);
+		Cairo.cairo_set_source(cairo, pattern.handle);
 	} else {
 		GdkGCValues values = new GdkGCValues();
 		OS.gdk_gc_get_values(handle, values);
@@ -2829,7 +2909,7 @@
 		color.pixel = values.foreground_pixel;
 		int /*long*/ colormap = OS.gdk_colormap_get_system();
 		OS.gdk_colormap_query_color(colormap, color.pixel, color);
-		Cairo.cairo_set_rgb_color(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF);
+		Cairo.cairo_set_source_rgba(cairo, (color.red & 0xFFFF) / (float)0xFFFF, (color.green & 0xFFFF) / (float)0xFFFF, (color.blue & 0xFFFF) / (float)0xFFFF, data.alpha / (float)0xFF);
 	}
 	data.foregroundPattern = pattern;
 }
@@ -3177,14 +3257,20 @@
 public void setTextAntialias(int antialias) {
     if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
 	if (data.cairo == 0 && antialias == SWT.DEFAULT) return;
-    switch (antialias) {
-        case SWT.DEFAULT: break;
-        case SWT.OFF: break;
-        case SWT.ON: break;
-        default:
-            SWT.error(SWT.ERROR_INVALID_ARGUMENT);
-    }
-    data.textAntialias = antialias;
+	int mode = 0;
+	switch (antialias) {
+		case SWT.DEFAULT: mode = Cairo.CAIRO_ANTIALIAS_DEFAULT; break;
+		case SWT.OFF: mode = Cairo.CAIRO_ANTIALIAS_NONE; break;
+		case SWT.ON: mode = Cairo.CAIRO_ANTIALIAS_GRAY;
+            break;
+		default:
+			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+	}
+    initCairo();
+    int /*long*/ options = Cairo.cairo_font_options_create();
+    Cairo.cairo_font_options_set_antialias(options, mode);
+    Cairo.cairo_set_font_options(data.cairo, options);
+    Cairo.cairo_font_options_destroy(options);
 }
 
 /** 
@@ -3211,20 +3297,21 @@
 	if (data.cairo == 0 && transform == null) return;
 	initCairo();
 	int /*long*/ cairo = data.cairo;
-	Cairo.cairo_concat_matrix(cairo, data.inverseMatrix);
+	Cairo.cairo_transform(cairo, data.inverseMatrix);
 	if (transform != null) {
-		Cairo.cairo_concat_matrix(cairo, transform.handle);
-		Cairo.cairo_matrix_copy(data.matrix, transform.handle);
-		Cairo.cairo_matrix_copy(data.inverseMatrix, transform.handle);
+		Cairo.cairo_transform(cairo, transform.handle);
+		double[] matrix = transform.handle;
+		Cairo.cairo_matrix_init(data.matrix, matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
+		Cairo.cairo_matrix_init(data.matrix, matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
 		Cairo.cairo_matrix_invert(data.inverseMatrix);
 	} else {
-		Cairo.cairo_matrix_set_identity(data.matrix);
-		Cairo.cairo_matrix_set_identity(data.inverseMatrix);
+		Cairo.cairo_matrix_init_identity(data.matrix);
+		Cairo.cairo_matrix_init_identity(data.inverseMatrix);
 	}
 	//TODO - round off problems
 	int /*long*/ clipRgn = data.clipRgn;
 	if (clipRgn != 0) {
-		int /*long*/ matrix = data.inverseMatrix;
+		double[] matrix = data.inverseMatrix;
 		int /*long*/ newRgn = OS.gdk_region_new();
 		int[] nRects = new int[1];
 		int /*long*/[] rects = new int /*long*/[1];
--- gtk/org/eclipse/swt/graphics/Image.java	2005-10-02 00:08:13.000000000 +0200
+++ gtk/org/eclipse/swt/graphics/Image.java	2005-10-02 00:10:44.000000000 +0200
@@ -552,10 +552,10 @@
 	if (surface != 0) return;
 	/* Generate the mask if necessary. */
 	if (transparentPixel != -1) createMask();
+	int[] w = new int[1], h = new int[1];
+	OS.gdk_drawable_get_size(pixmap, w, h);
+	int width = w[0], height = h[0];
 	if (mask != 0 || alpha != -1 || alphaData != null) {
-		int[] w = new int[1], h = new int[1];
-	 	OS.gdk_drawable_get_size(pixmap, w, h);
-	 	int width = w[0], height = h[0]; 	
 	 	int /*long*/ pixbuf = OS.gdk_pixbuf_new(OS.GDK_COLORSPACE_RGB, true, 8, width, height);
 		if (pixbuf == 0) SWT.error(SWT.ERROR_NO_HANDLES);
 		int /*long*/ colormap = OS.gdk_colormap_get_system();
@@ -616,14 +616,13 @@
 		}
 		surfaceData = OS.g_malloc(stride * height);
 		OS.memmove(surfaceData, pixels, stride * height);
-		surface = Cairo.cairo_surface_create_for_image(surfaceData, Cairo.CAIRO_FORMAT_ARGB32, width, height, stride);
+		surface = Cairo.cairo_image_surface_create_for_data(surfaceData, Cairo.CAIRO_FORMAT_ARGB32, width, height, stride);
 		OS.g_object_unref(pixbuf);
 	} else {
 		int /*long*/ xDisplay = OS.GDK_DISPLAY();
 		int /*long*/ xDrawable = OS.GDK_PIXMAP_XID(pixmap);
 		int /*long*/ xVisual = OS.gdk_x11_visual_get_xvisual(OS.gdk_visual_get_system());
-		int /*long*/ xColormap = OS.gdk_x11_colormap_get_xcolormap(OS.gdk_colormap_get_system());
-		surface = Cairo.cairo_xlib_surface_create(xDisplay, xDrawable, xVisual, 0, xColormap);
+		surface = Cairo.cairo_xlib_surface_create(xDisplay, xDrawable, xVisual, width, height);
 	}
 	/* Destroy the image mask if the there is a GC created on the image */
 	if (transparentPixel != -1 && memGC != null) destroyMask();
openSUSE Build Service is sponsored by