changeset 21:4f9c0fea3440

Path
author Frank Benoit <benoit@tionex.de>
date Mon, 07 Jan 2008 09:11:15 +0100
parents 55c4568a2bab
children b5521a2c27c2
files dwt/graphics/GC.d dwt/graphics/GCData.d dwt/graphics/GlyphMetrics.d dwt/graphics/Path.d dwt/graphics/Pattern.d dwt/internal/cairo/Cairo.d dwt/internal/gtk/c/cairotypes.d todo.txt
diffstat 8 files changed, 918 insertions(+), 182 deletions(-) [+]
line wrap: on
line diff
--- a/dwt/graphics/GC.d	Mon Jan 07 08:07:46 2008 +0100
+++ b/dwt/graphics/GC.d	Mon Jan 07 09:11:15 2008 +0100
@@ -12,11 +12,6 @@
 
 import dwt.graphics.Image;
 
-class GC{
-    void drawImage(Image, int, int, int, int, int, int, int, int ){}
-    void dispose(){}
-}
-/+++
 
 import dwt.internal.cairo.Cairo;
 import dwt.internal.gtk.OS;
@@ -24,6 +19,7 @@
 import dwt.internal.Converter;
 import dwt.internal.Compatibility;
 import dwt.SWT;
+import dwt.graphics.Color;
 import dwt.graphics.Drawable;
 import dwt.graphics.Resource;
 import dwt.graphics.Device;
@@ -32,14 +28,43 @@
 import dwt.graphics.GCData;
 import dwt.graphics.Image;
 import dwt.graphics.ImageData;
-import dwt.graphics.Path;
+//import dwt.graphics.Path;
 import dwt.graphics.Pattern;
 import dwt.graphics.Point;
 import dwt.graphics.RGB;
 import dwt.graphics.Rectangle;
 import dwt.graphics.Region;
 import dwt.graphics.Resource;
-import dwt.graphics.Transform;
+//import dwt.graphics.Transform;
+
+import dwt.internal.gtk.c.cairotypes;
+
+class GC{
+    void drawImage(Image, int, int, int, int, int, int, int, int ){}
+    void dispose(){}
+    bool isDisposed(){ return false; }
+    static void setCairoPatternColor(cairo_pattern_t * pattern, int offset, Color c, int alpha) {}
+    static void addCairoString(cairo_t* cairo, char[] str, float x, float y, Font font) {}
+    void initCairo() {}
+    void checkGC (int mask) {}
+        const static int FOREGROUND = 1 << 0;
+    const static int BACKGROUND = 1 << 1;
+    const static int FONT = 1 << 2;
+    const static int LINE_STYLE = 1 << 3;
+    const static int LINE_CAP = 1 << 4;
+    const static int LINE_JOIN = 1 << 5;
+    const static int LINE_WIDTH = 1 << 6;
+    const static int LINE_MITERLIMIT = 1 << 7;
+    const static int BACKGROUND_BG = 1 << 8;
+    const static int DRAW_OFFSET = 1 << 9;
+    const static int DRAW = FOREGROUND | LINE_WIDTH | LINE_STYLE  | LINE_CAP  | LINE_JOIN | LINE_MITERLIMIT | DRAW_OFFSET;
+    const static int FILL = BACKGROUND;
+
+
+    GCData data;
+}
+
+/+++
 
 /**
  * Class <code>GC</code> is where all of the drawing capabilities that are
@@ -177,7 +202,7 @@
 	if (device.tracking) device.new_Object(this);
 }
 
-static void addCairoString(int /*long*/ cairo, String string, float x, float y, Font font) {
+static void addCairoString(cairo_t* cairo, String string, float x, float y, Font font) {
 	byte[] buffer = Converter.wcsToMbcs(null, string, true);
 	if (OS.GTK_VERSION >= OS.VERSION(2, 8, 0)) {
 		int /*long*/ layout = OS.pango_cairo_create_layout(cairo);
@@ -3065,7 +3090,7 @@
 	Cairo.cairo_clip(cairo);
 }
 
-static void setCairoPatternColor(int /*long*/ pattern, int offset, Color c, int alpha) {
+static void setCairoPatternColor( cairo_pattern_t* pattern, int offset, Color c, int alpha) {
 	GdkColor color = c.handle;
 	double aa = (alpha & 0xFF) / (double)0xFF;
 	double red = ((color.red & 0xFFFF) / (double)0xFFFF);
--- a/dwt/graphics/GCData.d	Mon Jan 07 08:07:46 2008 +0100
+++ b/dwt/graphics/GCData.d	Mon Jan 07 09:11:15 2008 +0100
@@ -11,6 +11,7 @@
 module dwt.graphics.GCData;
 
 import dwt.internal.gtk.c.gdktypes;
+import dwt.internal.gtk.c.cairotypes;
 import dwt.SWT;
 import dwt.graphics.Device;
 import dwt.graphics.Pattern;
@@ -51,7 +52,7 @@
 	public int /*long*/ damageRgn;
 	public Image image;
 	public GdkDrawable* drawable;
-	public int /*long*/ cairo;
+	public cairo_t* cairo;
 	public double cairoXoffset, cairoYoffset;
 	public bool disposeCairo;
 	public double[] clippingTransform;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/graphics/GlyphMetrics.d	Mon Jan 07 09:11:15 2008 +0100
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+module dwt.graphics.GlyphMetrics;
+
+import dwt.SWT;
+import tango.text.convert.Format;
+/**
+ * Instances of this class represent glyph metrics.
+ * <p>
+ * The hashCode() method in this class uses the values of the public
+ * fields to compute the hash value. When storing instances of the
+ * class in hashed collections, do not modify these fields after the
+ * object has been inserted.
+ * </p>
+ * <p>
+ * 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.
+ * </p>
+ *
+ * @see TextStyle
+ * @see TextLayout
+ *
+ * @since 3.2
+ */
+public final class GlyphMetrics {
+
+	/**
+	 * the ascent of the GlyphMetrics
+	 */
+	public int ascent;
+
+	/**
+	 * the descent of the GlyphMetrics
+	 */
+	public int descent;
+
+	/**
+	 * the width of the GlyphMetrics
+	 */
+	public int width;
+
+/**
+ * Constructs an instance of this class with the given
+ * ascent, descent and width values.
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_INVALID_ARGUMENT - if the ascent, descent or width argument is negative</li>
+ * </ul>
+ */
+public this(int ascent, int descent, int width) {
+	if (ascent < 0 || descent < 0 || width < 0) {
+			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+	}
+	this.ascent = ascent;
+	this.descent = descent;
+	this.width = width;
+}
+
+/**
+ * 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 override int opEquals (Object object) {
+	if (object is this) return true;
+	if (auto metrics = cast(GlyphMetrics)object ){
+       return metrics.ascent == ascent && metrics.descent == descent && metrics.width == width;
+    }
+    return false;
+}
+
+
+/**
+ * Returns an integer hash code for the receiver. Any two
+ * objects that return <code>true</code> when passed to
+ * <code>equals</code> must return the same value for this
+ * method.
+ *
+ * @return the receiver's hash
+ *
+ * @see #equals(Object)
+ */
+public override hash_t toHash () {
+	return ascent ^ descent ^ width;
+}
+
+/**
+ * Returns a string containing a concise, human-readable
+ * description of the receiver.
+ *
+ * @return a string representation of the <code>GlyphMetrics</code>
+ */
+public override char[] toString () {
+	return Format( "GlyphMetrics {{{}, {}, {}}", ascent, descent, width ); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwt/graphics/Path.d	Mon Jan 07 09:11:15 2008 +0100
@@ -0,0 +1,585 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+module dwt.graphics.Path;
+
+import dwt.SWT;
+import dwt.internal.Compatibility;
+import dwt.internal.cairo.Cairo;
+import dwt.internal.gtk.c.cairotypes;
+import dwt.graphics.Resource;
+import dwt.graphics.Device;
+import dwt.graphics.Font;
+import dwt.graphics.GC;
+import dwt.graphics.GCData;
+import dwt.graphics.PathData;
+
+import tango.stdc.string;
+import tango.text.convert.Format;
+
+/**
+ * Instances of this class represent paths through the two-dimensional
+ * coordinate system. Paths do not have to be continuous, and can be
+ * described using lines, rectangles, arcs, cubic or quadratic bezier curves,
+ * glyphs, or other paths.
+ * <p>
+ * Application code must explicitly invoke the <code>Path.dispose()</code>
+ * method to release the operating system resources managed by each instance
+ * when those instances are no longer required.
+ * </p>
+ * <p>
+ * This class requires the operating system's advanced graphics subsystem
+ * which may not be available on some platforms.
+ * </p>
+ *
+ * @since 3.1
+ */
+public class Path : Resource {
+
+	/**
+	 * the OS resource for the Path
+	 * (Warning: This field is platform dependent)
+	 * <p>
+	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
+	 * public API. It is marked public only so that it can be shared
+	 * within the packages provided by SWT. It is not available on all
+	 * platforms and should never be accessed from application code.
+	 * </p>
+	 */
+	public cairo_t* handle;
+
+	bool moved, closed = true;
+
+/**
+ * Constructs a new empty Path.
+ * <p>
+ * This operation requires the operating system's advanced
+ * graphics subsystem which may not be available on some
+ * platforms.
+ * </p>
+ *
+ * @param device the device on which to allocate the path
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the device is null and there is no current device</li>
+ * </ul>
+ * @exception SWTException <ul>
+ *    <li>ERROR_NO_GRAPHICS_LIBRARY - if advanced graphics are not available</li>
+ * </ul>
+ * @exception SWTError <ul>
+ *    <li>ERROR_NO_HANDLES if a handle for the path could not be obtained</li>
+ * </ul>
+ *
+ * @see #dispose()
+ */
+public this (Device device) {
+	if (device is null) device = Device.getDevice();
+	if (device is null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	this.device = device;
+	device.checkCairo();
+	auto surface = Cairo.cairo_image_surface_create(cast(cairo_format_t)Cairo.CAIRO_FORMAT_ARGB32, 1, 1);
+	if (surface is null) SWT.error(SWT.ERROR_NO_HANDLES);
+	handle = Cairo.cairo_create(surface);
+	Cairo.cairo_surface_destroy(surface);
+	if (handle is null) SWT.error(SWT.ERROR_NO_HANDLES);
+	if (device.tracking) device.new_Object(this);
+}
+
+/**
+ * Adds to the receiver a circular or elliptical arc that lies within
+ * the specified rectangular area.
+ * <p>
+ * The resulting arc begins at <code>startAngle</code> and extends
+ * for <code>arcAngle</code> degrees.
+ * Angles are interpreted such that 0 degrees is at the 3 o'clock
+ * position. A positive value indicates a counter-clockwise rotation
+ * while a negative value indicates a clockwise rotation.
+ * </p><p>
+ * The center of the arc is the center of the rectangle whose origin
+ * is (<code>x</code>, <code>y</code>) and whose size is specified by the
+ * <code>width</code> and <code>height</code> arguments.
+ * </p><p>
+ * The resulting arc covers an area <code>width + 1</code> pixels wide
+ * by <code>height + 1</code> pixels tall.
+ * </p>
+ *
+ * @param x the x coordinate of the upper-left corner of the arc
+ * @param y the y coordinate of the upper-left corner of the arc
+ * @param width the width of the arc
+ * @param height the height of the arc
+ * @param startAngle the beginning angle
+ * @param arcAngle the angular extent of the arc, relative to the start angle
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public void addArc(float x, float y, float width, float height, float startAngle, float arcAngle) {
+	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+	moved = true;
+	if (width == height) {
+		float angle = -startAngle * cast(float)Compatibility.PI / 180;
+		if (closed) Cairo.cairo_move_to(handle, (x + width / 2f) + width / 2f * Math.cos(angle), (y + height / 2f) + height / 2f * Math.sin(angle));
+		if (arcAngle >= 0) {
+			Cairo.cairo_arc_negative(handle, x + width / 2f, y + height / 2f, width / 2f, angle, -(startAngle + arcAngle) * cast(float)Compatibility.PI / 180);
+		} else {
+			Cairo.cairo_arc(handle, x + width / 2f, y + height / 2f, width / 2f, angle, -(startAngle + arcAngle) * cast(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);
+		float angle = -startAngle * cast(float)Compatibility.PI / 180;
+		if (closed) Cairo.cairo_move_to(handle, Math.cos(angle), Math.sin(angle));
+		if (arcAngle >= 0) {
+			Cairo.cairo_arc_negative(handle, 0, 0, 1, angle, -(startAngle + arcAngle) * cast(float)Compatibility.PI / 180);
+		} else {
+			Cairo.cairo_arc(handle, 0, 0, 1, angle, -(startAngle + arcAngle) * cast(float)Compatibility.PI / 180);
+		}
+		Cairo.cairo_restore(handle);
+	}
+	closed = false;
+	if (Math.abs(arcAngle) >= 360) close();
+}
+
+/**
+ * Adds to the receiver the path described by the parameter.
+ *
+ * @param path the path to add to the receiver
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the parameter is null</li>
+ *    <li>ERROR_INVALID_ARGUMENT - if the parameter has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public void addPath(Path path) {
+	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+	if (path is null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	if (path.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+	moved = false;
+	auto copy = Cairo.cairo_copy_path(path.handle);
+	if (copy is null) SWT.error(SWT.ERROR_NO_HANDLES);
+	Cairo.cairo_append_path(handle, copy);
+	Cairo.cairo_path_destroy(copy);
+	closed = path.closed;
+}
+
+/**
+ * Adds to the receiver the rectangle specified by x, y, width and height.
+ *
+ * @param x the x coordinate of the rectangle to add
+ * @param y the y coordinate of the rectangle to add
+ * @param width the width of the rectangle to add
+ * @param height the height of the rectangle to add
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public void addRectangle(float x, float y, float width, float height) {
+	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+	moved = false;
+	Cairo.cairo_rectangle(handle, x, y, width, height);
+	closed = true;
+}
+
+/**
+ * Adds to the receiver the pattern of glyphs generated by drawing
+ * the given string using the given font starting at the point (x, y).
+ *
+ * @param string the text to use
+ * @param x the x coordinate of the starting point
+ * @param y the y coordinate of the starting point
+ * @param font the font to use
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the font is null</li>
+ *    <li>ERROR_INVALID_ARGUMENT - if the font has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public void addString(char[] str, float x, float y, Font font) {
+	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+	if (font == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	if (font.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+	moved = false;
+	GC.addCairoString(handle, str, x, y, font);
+	closed = true;
+}
+
+/**
+ * Closes the current sub path by adding to the receiver a line
+ * from the current point of the path back to the starting point
+ * of the sub path.
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public void close() {
+	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+	Cairo.cairo_close_path(handle);
+	moved = false;
+	closed = true;
+}
+
+/**
+ * Returns <code>true</code> if the specified point is contained by
+ * the receiver and false otherwise.
+ * <p>
+ * If outline is <code>true</code>, the point (x, y) checked for containment in
+ * the receiver's outline. If outline is <code>false</code>, the point is
+ * checked to see if it is contained within the bounds of the (closed) area
+ * covered by the receiver.
+ *
+ * @param x the x coordinate of the point to test for containment
+ * @param y the y coordinate of the point to test for containment
+ * @param gc the GC to use when testing for containment
+ * @param outline controls whether to check the outline or contained area of the path
+ * @return <code>true</code> if the path contains the point and <code>false</code> otherwise
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the gc is null</li>
+ *    <li>ERROR_INVALID_ARGUMENT - if the gc has been disposed</li>
+ * </ul>
+ * @exception SWTException <ul>
+ *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public bool contains(float x, float y, GC gc, bool outline) {
+	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+	if (gc == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	if (gc.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+	//TODO - see Windows
+	gc.initCairo();
+	gc.checkGC(GC.LINE_CAP | GC.LINE_JOIN | GC.LINE_STYLE | GC.LINE_WIDTH);
+	bool result = false;
+	auto cairo = gc.data.cairo;
+	auto copy = Cairo.cairo_copy_path(handle);
+	if (copy is null) 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 {
+		result = Cairo.cairo_in_fill(cairo, x, y) != 0;
+	}
+	Cairo.cairo_new_path(cairo);
+	return result;
+}
+
+/**
+ * Adds to the receiver a cubic bezier curve based on the parameters.
+ *
+ * @param cx1 the x coordinate of the first control point of the spline
+ * @param cy1 the y coordinate of the first control of the spline
+ * @param cx2 the x coordinate of the second control of the spline
+ * @param cy2 the y coordinate of the second control of the spline
+ * @param x the x coordinate of the end point of the spline
+ * @param y the y coordinate of the end point of the spline
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public void cubicTo(float cx1, float cy1, float cx2, float cy2, float x, float y) {
+	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+	if (!moved) {
+		double currentX, currentY;
+		Cairo.cairo_get_current_point(handle, &currentX, &currentY);
+		Cairo.cairo_move_to(handle, currentX, currentY);
+		moved = true;
+	}
+	Cairo.cairo_curve_to(handle, cx1, cy1, cx2, cy2, x, y);
+	closed = false;
+}
+
+/**
+ * Replaces the first four elements in the parameter with values that
+ * describe the smallest rectangle that will completely contain the
+ * receiver (i.e. the bounding box).
+ *
+ * @param bounds the array to hold the result
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the parameter is null</li>
+ *    <li>ERROR_INVALID_ARGUMENT - if the parameter is too small to hold the bounding box</li>
+ * </ul>
+ * @exception SWTException <ul>
+ *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public void getBounds(float[] bounds) {
+	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+	if (bounds == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	if (bounds.length < 4) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+	auto copy = Cairo.cairo_copy_path(handle);
+	if (copy is null) SWT.error(SWT.ERROR_NO_HANDLES);
+	cairo_path_t* path = new cairo_path_t();
+	memmove(path, copy, cairo_path_t.sizeof);
+	double minX = 0, minY = 0, maxX = 0, maxY = 0;
+	if (path.num_data > 0) {
+		minX = minY = double.max;
+		maxX = maxY = -double.max;
+		int i = 0;
+		cairo_path_data_t* data = new cairo_path_data_t();
+		while (i < path.num_data) {
+			*data = path.data[i];
+			switch (data.type) {
+				case Cairo.CAIRO_PATH_MOVE_TO:
+					minX = Math.min(minX, path.data[i+1].x);
+					minY = Math.min(minY, path.data[i+1].y);
+					maxX = Math.max(maxX, path.data[i+1].x);
+					maxY = Math.max(maxY, path.data[i+1].y);
+					break;
+				case Cairo.CAIRO_PATH_LINE_TO:
+                    minX = Math.min(minX, path.data[i+1].x);
+                    minY = Math.min(minY, path.data[i+1].y);
+                    maxX = Math.max(maxX, path.data[i+1].x);
+                    maxY = Math.max(maxY, path.data[i+1].y);
+					break;
+				case Cairo.CAIRO_PATH_CURVE_TO:
+                    minX = Math.min(minX, path.data[i+1].x);
+                    minY = Math.min(minY, path.data[i+1].y);
+                    maxX = Math.max(maxX, path.data[i+1].x);
+                    maxY = Math.max(maxY, path.data[i+1].y);
+                    minX = Math.min(minX, path.data[i+2].x);
+                    minY = Math.min(minY, path.data[i+2].y);
+                    maxX = Math.max(maxX, path.data[i+2].x);
+                    maxY = Math.max(maxY, path.data[i+2].y);
+                    minX = Math.min(minX, path.data[i+3].x);
+                    minY = Math.min(minY, path.data[i+3].y);
+                    maxX = Math.max(maxX, path.data[i+3].x);
+                    maxY = Math.max(maxY, path.data[i+3].y);
+					break;
+				case Cairo.CAIRO_PATH_CLOSE_PATH: break;
+			}
+			i += data.length;
+		}
+	}
+	bounds[0] = cast(float)minX;
+	bounds[1] = cast(float)minY;
+	bounds[2] = cast(float)(maxX - minX);
+	bounds[3] = cast(float)(maxY - minY);
+	Cairo.cairo_path_destroy(copy);
+}
+
+/**
+ * Replaces the first two elements in the parameter with values that
+ * describe the current point of the path.
+ *
+ * @param point the array to hold the result
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the parameter is null</li>
+ *    <li>ERROR_INVALID_ARGUMENT - if the parameter is too small to hold the end point</li>
+ * </ul>
+ * @exception SWTException <ul>
+ *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public void getCurrentPoint(float[] point) {
+	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+	if (point == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	if (point.length < 2) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+	double x, y;
+	Cairo.cairo_get_current_point(handle, &x, &y);
+	point[0] = cast(float)x;
+	point[1] = cast(float)y;
+}
+
+/**
+ * Returns a device independent representation of the receiver.
+ *
+ * @return the PathData for the receiver
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ *
+ * @see PathData
+ */
+public PathData getPathData() {
+	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+	auto copy = Cairo.cairo_copy_path(handle);
+	if (copy is null) SWT.error(SWT.ERROR_NO_HANDLES);
+	cairo_path_t* path = new cairo_path_t();
+	*path = *copy;
+	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) {
+			switch (data.type) {
+				case Cairo.CAIRO_PATH_MOVE_TO:
+					types[typeIndex++] = SWT.PATH_MOVE_TO;
+					pts[ptsIndex++] = cast(float)path.data[i+1].x;
+					pts[ptsIndex++] = cast(float)path.data[i+1].y;
+					break;
+				case Cairo.CAIRO_PATH_LINE_TO:
+					types[typeIndex++] = SWT.PATH_LINE_TO;
+                    pts[ptsIndex++] = cast(float)path.data[i+1].x;
+                    pts[ptsIndex++] = cast(float)path.data[i+1].y;
+					break;
+				case Cairo.CAIRO_PATH_CURVE_TO:
+					types[typeIndex++] = SWT.PATH_CUBIC_TO;
+                    pts[ptsIndex++] = cast(float)path.data[i+1].x;
+                    pts[ptsIndex++] = cast(float)path.data[i+1].y;
+                    pts[ptsIndex++] = cast(float)path.data[i+2].x;
+                    pts[ptsIndex++] = cast(float)path.data[i+2].y;
+                    pts[ptsIndex++] = cast(float)path.data[i+3].x;
+                    pts[ptsIndex++] = cast(float)path.data[i+3].y;
+					break;
+				case Cairo.CAIRO_PATH_CLOSE_PATH:
+					types[typeIndex++] = SWT.PATH_CLOSE;
+					break;
+			}
+			i += data.length;
+		}
+	}
+	if (typeIndex != types.length) {
+		types.length = typeIndex;
+	}
+	if (ptsIndex != pts.length) {
+        pts.length = ptsIndex;
+	}
+	Cairo.cairo_path_destroy(copy);
+	PathData result = new PathData();
+	result.types = types;
+	result.points = pts;
+	return result;
+}
+
+/**
+ * Adds to the receiver a line from the current point to
+ * the point specified by (x, y).
+ *
+ * @param x the x coordinate of the end of the line to add
+ * @param y the y coordinate of the end of the line to add
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public void lineTo(float x, float y) {
+	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+	if (!moved) {
+		double currentX, currentY;
+		Cairo.cairo_get_current_point(handle, &currentX, &currentY);
+		Cairo.cairo_move_to(handle, currentX, currentY);
+		moved = true;
+	}
+	Cairo.cairo_line_to(handle, x, y);
+	closed = false;
+}
+
+/**
+ * Sets the current point of the receiver to the point
+ * specified by (x, y). Note that this starts a new
+ * sub path.
+ *
+ * @param x the x coordinate of the new end point
+ * @param y the y coordinate of the new end point
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public void moveTo(float x, float y) {
+	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+	/*
+	* Bug in Cairo.  If cairo_move_to() is not called at the
+	* begining of a subpath, the first cairo_line_to() or
+	* cairo_curve_to() segment do not output anything.  The fix
+	* is to detect that the app did not call cairo_move_to()
+	* before those calls and call it explicitly.
+	*/
+	moved = true;
+	Cairo.cairo_move_to(handle, x, y);
+	closed = true;
+}
+
+/**
+ * Adds to the receiver a quadratic curve based on the parameters.
+ *
+ * @param cx the x coordinate of the control point of the spline
+ * @param cy the y coordinate of the control point of the spline
+ * @param x the x coordinate of the end point of the spline
+ * @param y the y coordinate of the end point of the spline
+ *
+ * @exception SWTException <ul>
+ *    <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
+ * </ul>
+ */
+public void quadTo(float cx, float cy, float x, float y) {
+	if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+	double currentX, currentY;
+	Cairo.cairo_get_current_point(handle, &currentX, &currentY);
+	if (!moved) {
+		Cairo.cairo_move_to(handle, currentX, currentY);
+		moved = true;
+	}
+	float x0 = cast(float)currentX;
+	float y0 = cast(float)currentY;
+	float cx1 = x0 + 2 * (cx - x0) / 3;
+	float cy1 = y0 + 2 * (cy - y0) / 3;
+	float cx2 = cx1 + (x - x0) / 3;
+	float cy2 = cy1 + (y - y0) / 3;
+	Cairo.cairo_curve_to(handle, cx1, cy1, cx2, cy2, x, y);
+	closed = false;
+}
+
+/**
+ * Disposes of the operating system resources associated with
+ * the Path. Applications must dispose of all Paths that
+ * they allocate.
+ */
+public void dispose() {
+	if (handle is null) return;
+	Cairo.cairo_destroy(handle);
+	handle = null;
+	if (device.tracking) device.dispose_Object(this);
+	device = null;
+}
+
+/**
+ * Returns <code>true</code> if the Path has been disposed,
+ * and <code>false</code> otherwise.
+ * <p>
+ * This method gets the dispose state for the Path.
+ * When a Path has been disposed, it is an error to
+ * invoke any other method using the Path.
+ *
+ * @return <code>true</code> when the Path is disposed, and <code>false</code> otherwise
+ */
+public bool isDisposed() {
+	return handle is null;
+}
+
+/**
+ * Returns a string containing a concise, human-readable
+ * description of the receiver.
+ *
+ * @return a string representation of the receiver
+ */
+public char[] toString() {
+	if (isDisposed()) return "Path {*DISPOSED*}";
+	return Format( "Path {{{}}", handle );
+}
+
+}
--- a/dwt/graphics/Pattern.d	Mon Jan 07 08:07:46 2008 +0100
+++ b/dwt/graphics/Pattern.d	Mon Jan 07 09:11:15 2008 +0100
@@ -10,11 +10,17 @@
  *******************************************************************************/
 module dwt.graphics.Pattern;
 
-class Pattern{
-}
-/++++
-import dwt.*;
-import dwt.internal.cairo.*;
+
+import dwt.SWT;
+import dwt.graphics.Resource;
+import dwt.graphics.Color;
+import dwt.graphics.GC;
+import dwt.graphics.Device;
+import dwt.graphics.Image;
+import dwt.internal.cairo.Cairo;
+import dwt.internal.gtk.c.cairotypes;
+
+import tango.text.convert.Format;
 
 /**
  * Instances of this class represent patterns to use while drawing. Patterns
@@ -31,7 +37,7 @@
  *
  * @since 3.1
  */
-public class Pattern extends Resource {
+public class Pattern : Resource {
 
 	/**
 	 * the OS resource for the Pattern
@@ -43,7 +49,7 @@
 	 * platforms and should never be accessed from application code.
 	 * </p>
 	 */
-	public int /*long*/ handle;
+	public cairo_pattern_t* handle;
 
 /**
  * Constructs a new Pattern given an image. Drawing with the resulting
@@ -70,17 +76,17 @@
  *
  * @see #dispose()
  */
-public Pattern(Device device, Image image) {
-	if (device == null) device = Device.getDevice();
-	if (device == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
-	if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+public this(Device device, Image image) {
+	if (device is null) device = Device.getDevice();
+	if (device is null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	if (image is null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
 	if (image.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
 	this.device = device;
 	device.checkCairo();
 	image.createSurface();
 	handle = Cairo.cairo_pattern_create_for_surface(image.surface);
-	if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
-	Cairo.cairo_pattern_set_extend(handle, Cairo.CAIRO_EXTEND_REPEAT);
+	if (handle is null) SWT.error(SWT.ERROR_NO_HANDLES);
+	Cairo.cairo_pattern_set_extend(handle, cast(cairo_extend_t) Cairo.CAIRO_EXTEND_REPEAT);
 	if (device.tracking) device.new_Object(this);
 }
 
@@ -116,7 +122,7 @@
  *
  * @see #dispose()
  */
-public Pattern(Device device, float x1, float y1, float x2, float y2, Color color1, Color color2) {
+public this(Device device, float x1, float y1, float x2, float y2, Color color1, Color color2) {
 	this(device, x1, y1, x2, y2, color1, 0xFF, color2, 0xFF);
 }
 /**
@@ -155,20 +161,20 @@
  *
  * @since 3.2
  */
-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);
+public this(Device device, float x1, float y1, float x2, float y2, Color color1, int alpha1, Color color2, int alpha2) {
+	if (device is null) device = Device.getDevice();
+	if (device is null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	if (color1 is null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
 	if (color1.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
-	if (color2 == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+	if (color2 is null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
 	if (color2.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
 	this.device = device;
 	device.checkCairo();
 	handle = Cairo.cairo_pattern_create_linear(x1, y1, x2, y2);
-	if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+	if (handle is null) SWT.error(SWT.ERROR_NO_HANDLES);
 	GC.setCairoPatternColor(handle, 0, color1, alpha1);
 	GC.setCairoPatternColor(handle, 1, color2, alpha2);
-	Cairo.cairo_pattern_set_extend(handle, Cairo.CAIRO_EXTEND_REPEAT);
+	Cairo.cairo_pattern_set_extend(handle, cast(cairo_extend_t)Cairo.CAIRO_EXTEND_REPEAT);
 	if (device.tracking) device.new_Object(this);
 }
 
@@ -178,10 +184,10 @@
  * they allocate.
  */
 public void dispose() {
-	if (handle == 0) return;
+	if (handle is null) return;
 	if (device.isDisposed()) return;
 	Cairo.cairo_pattern_destroy(handle);
-	handle = 0;
+	handle = null;
 	if (device.tracking) device.dispose_Object(this);
 	device = null;
 }
@@ -196,8 +202,8 @@
  *
  * @return <code>true</code> when the Pattern is disposed, and <code>false</code> otherwise
  */
-public boolean isDisposed() {
-	return handle == 0;
+public bool isDisposed() {
+	return handle is null;
 }
 
 /**
@@ -206,10 +212,9 @@
  *
  * @return a string representation of the receiver
  */
-public String toString() {
+public char[] toString() {
 	if (isDisposed()) return "Pattern {*DISPOSED*}";
-	return "Pattern {" + handle + "}";
+	return Format( "Pattern {{{}}", handle );
 }
 
 }
-++++/
\ No newline at end of file
--- a/dwt/internal/cairo/Cairo.d	Mon Jan 07 08:07:46 2008 +0100
+++ b/dwt/internal/cairo/Cairo.d	Mon Jan 07 09:11:15 2008 +0100
@@ -127,148 +127,144 @@
     mixin ForwardGtkCairoCFunc!(.cairo_path_t_sizeof );
     mixin ForwardGtkCairoCFunc!(.cairo_text_extents_t_sizeof );
     mixin ForwardGtkCairoCFunc!(.CAIRO_VERSION_ENCODE);
-    mixin ForwardGtkCairoCFunc!(._cairo_append_path);
-    mixin ForwardGtkCairoCFunc!(._cairo_arc);
-    mixin ForwardGtkCairoCFunc!(._cairo_arc_negative);
-    mixin ForwardGtkCairoCFunc!(._cairo_clip);
-    mixin ForwardGtkCairoCFunc!(._cairo_clip_preserve);
-    mixin ForwardGtkCairoCFunc!(._cairo_close_path);
-    mixin ForwardGtkCairoCFunc!(._cairo_copy_page);
-    mixin ForwardGtkCairoCFunc!(._cairo_copy_path);
-    mixin ForwardGtkCairoCFunc!(._cairo_copy_path_flat);
-    mixin ForwardGtkCairoCFunc!(._cairo_create);
-    mixin ForwardGtkCairoCFunc!(._cairo_curve_to);
-    mixin ForwardGtkCairoCFunc!(._cairo_destroy);
-    mixin ForwardGtkCairoCFunc!(._cairo_device_to_user);
-    mixin ForwardGtkCairoCFunc!(._cairo_device_to_user_distance);
-    mixin ForwardGtkCairoCFunc!(._cairo_fill);
-    mixin ForwardGtkCairoCFunc!(._cairo_fill_extents);
-    mixin ForwardGtkCairoCFunc!(._cairo_fill_preserve);
-    mixin ForwardGtkCairoCFunc!(._cairo_font_extents);
-    mixin ForwardGtkCairoCFunc!(._cairo_font_options_create);
-    mixin ForwardGtkCairoCFunc!(._cairo_font_options_destroy);
-    mixin ForwardGtkCairoCFunc!(._cairo_font_options_get_antialias);
-    mixin ForwardGtkCairoCFunc!(._cairo_font_options_set_antialias);
-    mixin ForwardGtkCairoCFunc!(._cairo_get_antialias);
-    mixin ForwardGtkCairoCFunc!(._cairo_get_current_point);
-    mixin ForwardGtkCairoCFunc!(._cairo_get_fill_rule);
-    mixin ForwardGtkCairoCFunc!(._cairo_get_font_face);
-    mixin ForwardGtkCairoCFunc!(._cairo_get_font_matrix);
-    mixin ForwardGtkCairoCFunc!(._cairo_get_font_options);
-    mixin ForwardGtkCairoCFunc!(._cairo_get_line_cap);
-    mixin ForwardGtkCairoCFunc!(._cairo_get_line_join);
-    mixin ForwardGtkCairoCFunc!(._cairo_get_line_width);
-    mixin ForwardGtkCairoCFunc!(._cairo_get_matrix);
-    mixin ForwardGtkCairoCFunc!(._cairo_get_miter_limit);
-    mixin ForwardGtkCairoCFunc!(._cairo_get_operator);
-    mixin ForwardGtkCairoCFunc!(._cairo_get_source);
-    mixin ForwardGtkCairoCFunc!(._cairo_get_target);
-    mixin ForwardGtkCairoCFunc!(._cairo_get_tolerance);
-    mixin ForwardGtkCairoCFunc!(._cairo_glyph_extents);
-    mixin ForwardGtkCairoCFunc!(._cairo_glyph_path);
-    mixin ForwardGtkCairoCFunc!(._cairo_identity_matrix);
-    mixin ForwardGtkCairoCFunc!(._cairo_image_surface_create);
     +/
+    mixin ForwardGtkCairoCFunc!(.cairo_append_path);
+    mixin ForwardGtkCairoCFunc!(.cairo_arc);
+    mixin ForwardGtkCairoCFunc!(.cairo_arc_negative);
+    mixin ForwardGtkCairoCFunc!(.cairo_clip);
+    mixin ForwardGtkCairoCFunc!(.cairo_clip_preserve);
+    mixin ForwardGtkCairoCFunc!(.cairo_close_path);
+    mixin ForwardGtkCairoCFunc!(.cairo_copy_page);
+    mixin ForwardGtkCairoCFunc!(.cairo_copy_path);
+    mixin ForwardGtkCairoCFunc!(.cairo_copy_path_flat);
+    mixin ForwardGtkCairoCFunc!(.cairo_create);
+    mixin ForwardGtkCairoCFunc!(.cairo_curve_to);
+    mixin ForwardGtkCairoCFunc!(.cairo_destroy);
+    mixin ForwardGtkCairoCFunc!(.cairo_device_to_user);
+    mixin ForwardGtkCairoCFunc!(.cairo_device_to_user_distance);
+    mixin ForwardGtkCairoCFunc!(.cairo_fill);
+    mixin ForwardGtkCairoCFunc!(.cairo_fill_extents);
+    mixin ForwardGtkCairoCFunc!(.cairo_fill_preserve);
+    mixin ForwardGtkCairoCFunc!(.cairo_font_extents);
+    mixin ForwardGtkCairoCFunc!(.cairo_font_options_create);
+    mixin ForwardGtkCairoCFunc!(.cairo_font_options_destroy);
+    mixin ForwardGtkCairoCFunc!(.cairo_font_options_get_antialias);
+    mixin ForwardGtkCairoCFunc!(.cairo_font_options_set_antialias);
+    mixin ForwardGtkCairoCFunc!(.cairo_get_antialias);
+    mixin ForwardGtkCairoCFunc!(.cairo_get_current_point);
+    mixin ForwardGtkCairoCFunc!(.cairo_get_fill_rule);
+    mixin ForwardGtkCairoCFunc!(.cairo_get_font_face);
+    mixin ForwardGtkCairoCFunc!(.cairo_get_font_matrix);
+    mixin ForwardGtkCairoCFunc!(.cairo_get_font_options);
+    mixin ForwardGtkCairoCFunc!(.cairo_get_line_cap);
+    mixin ForwardGtkCairoCFunc!(.cairo_get_line_join);
+    mixin ForwardGtkCairoCFunc!(.cairo_get_line_width);
+    mixin ForwardGtkCairoCFunc!(.cairo_get_matrix);
+    mixin ForwardGtkCairoCFunc!(.cairo_get_miter_limit);
+    mixin ForwardGtkCairoCFunc!(.cairo_get_operator);
+    mixin ForwardGtkCairoCFunc!(.cairo_get_source);
+    mixin ForwardGtkCairoCFunc!(.cairo_get_target);
+    mixin ForwardGtkCairoCFunc!(.cairo_get_tolerance);
+    mixin ForwardGtkCairoCFunc!(.cairo_glyph_extents);
+    mixin ForwardGtkCairoCFunc!(.cairo_glyph_path);
+    mixin ForwardGtkCairoCFunc!(.cairo_identity_matrix);
+    mixin ForwardGtkCairoCFunc!(.cairo_image_surface_create);
     mixin ForwardGtkCairoCFunc!(.cairo_image_surface_create_for_data);
-    /+
-    mixin ForwardGtkCairoCFunc!(._cairo_image_surface_get_height);
-    mixin ForwardGtkCairoCFunc!(._cairo_image_surface_get_width);
-    mixin ForwardGtkCairoCFunc!(._cairo_in_fill);
-    mixin ForwardGtkCairoCFunc!(._cairo_in_stroke);
-    mixin ForwardGtkCairoCFunc!(._cairo_line_to);
-    mixin ForwardGtkCairoCFunc!(._cairo_mask);
-    mixin ForwardGtkCairoCFunc!(._cairo_mask_surface);
-    mixin ForwardGtkCairoCFunc!(._cairo_matrix_init);
-    mixin ForwardGtkCairoCFunc!(._cairo_matrix_init_identity);
-    mixin ForwardGtkCairoCFunc!(._cairo_matrix_init_rotate);
-    mixin ForwardGtkCairoCFunc!(._cairo_matrix_init_scale);
-    mixin ForwardGtkCairoCFunc!(._cairo_matrix_init_translate);
-    mixin ForwardGtkCairoCFunc!(._cairo_matrix_invert);
-    mixin ForwardGtkCairoCFunc!(._cairo_matrix_multiply);
-    mixin ForwardGtkCairoCFunc!(._cairo_matrix_rotate);
-    mixin ForwardGtkCairoCFunc!(._cairo_matrix_scale);
-    mixin ForwardGtkCairoCFunc!(._cairo_matrix_transform_distance);
-    mixin ForwardGtkCairoCFunc!(._cairo_matrix_transform_point);
-    mixin ForwardGtkCairoCFunc!(._cairo_matrix_translate);
-    mixin ForwardGtkCairoCFunc!(._cairo_move_to);
-    mixin ForwardGtkCairoCFunc!(._cairo_new_path);
-    mixin ForwardGtkCairoCFunc!(._cairo_paint);
-    mixin ForwardGtkCairoCFunc!(._cairo_paint_with_alpha);
-    mixin ForwardGtkCairoCFunc!(._cairo_path_destroy);
-    mixin ForwardGtkCairoCFunc!(._cairo_pattern_add_color_stop_rgb);
-    mixin ForwardGtkCairoCFunc!(._cairo_pattern_add_color_stop_rgba);
-    mixin ForwardGtkCairoCFunc!(._cairo_pattern_create_for_surface);
-    mixin ForwardGtkCairoCFunc!(._cairo_pattern_create_linear);
-    mixin ForwardGtkCairoCFunc!(._cairo_pattern_create_radial);
-    mixin ForwardGtkCairoCFunc!(._cairo_pattern_destroy);
-    mixin ForwardGtkCairoCFunc!(._cairo_pattern_get_extend);
-    mixin ForwardGtkCairoCFunc!(._cairo_pattern_get_filter);
-    mixin ForwardGtkCairoCFunc!(._cairo_pattern_get_matrix);
-    mixin ForwardGtkCairoCFunc!(._cairo_pattern_reference);
-    mixin ForwardGtkCairoCFunc!(._cairo_pattern_set_extend);
-    mixin ForwardGtkCairoCFunc!(._cairo_pattern_set_filter);
-    mixin ForwardGtkCairoCFunc!(._cairo_pattern_set_matrix);
-    mixin ForwardGtkCairoCFunc!(._cairo_pdf_surface_set_size);
-    mixin ForwardGtkCairoCFunc!(._cairo_ps_surface_set_size);
-    mixin ForwardGtkCairoCFunc!(._cairo_rectangle);
-    mixin ForwardGtkCairoCFunc!(._cairo_reference);
-    mixin ForwardGtkCairoCFunc!(._cairo_rel_curve_to);
-    mixin ForwardGtkCairoCFunc!(._cairo_rel_line_to);
-    mixin ForwardGtkCairoCFunc!(._cairo_rel_move_to);
-    mixin ForwardGtkCairoCFunc!(._cairo_reset_clip);
-    mixin ForwardGtkCairoCFunc!(._cairo_restore);
-    mixin ForwardGtkCairoCFunc!(._cairo_rotate);
-    mixin ForwardGtkCairoCFunc!(._cairo_save);
-    mixin ForwardGtkCairoCFunc!(._cairo_scale);
-    mixin ForwardGtkCairoCFunc!(._cairo_select_font_face);
-    mixin ForwardGtkCairoCFunc!(._cairo_set_antialias);
-    mixin ForwardGtkCairoCFunc!(._cairo_set_dash);
-    mixin ForwardGtkCairoCFunc!(._cairo_set_fill_rule);
-    mixin ForwardGtkCairoCFunc!(._cairo_set_font_face);
-    mixin ForwardGtkCairoCFunc!(._cairo_set_font_matrix);
-    mixin ForwardGtkCairoCFunc!(._cairo_set_font_options);
-    mixin ForwardGtkCairoCFunc!(._cairo_set_font_size);
-    mixin ForwardGtkCairoCFunc!(._cairo_set_line_cap);
-    mixin ForwardGtkCairoCFunc!(._cairo_set_line_join);
-    mixin ForwardGtkCairoCFunc!(._cairo_set_line_width);
-    mixin ForwardGtkCairoCFunc!(._cairo_set_matrix);
-    mixin ForwardGtkCairoCFunc!(._cairo_set_miter_limit);
-    mixin ForwardGtkCairoCFunc!(._cairo_set_operator);
-    mixin ForwardGtkCairoCFunc!(._cairo_set_source);
-    mixin ForwardGtkCairoCFunc!(._cairo_set_source_rgb);
-    mixin ForwardGtkCairoCFunc!(._cairo_set_source_rgba);
-    mixin ForwardGtkCairoCFunc!(._cairo_set_source_surface);
-    mixin ForwardGtkCairoCFunc!(._cairo_set_tolerance);
-    mixin ForwardGtkCairoCFunc!(._cairo_show_glyphs);
-    mixin ForwardGtkCairoCFunc!(._cairo_show_page);
-    mixin ForwardGtkCairoCFunc!(._cairo_show_text);
-    mixin ForwardGtkCairoCFunc!(._cairo_status);
-    mixin ForwardGtkCairoCFunc!(._cairo_status_to_string);
-    mixin ForwardGtkCairoCFunc!(._cairo_stroke);
-    mixin ForwardGtkCairoCFunc!(._cairo_stroke_extents);
-    mixin ForwardGtkCairoCFunc!(._cairo_stroke_preserve);
-    mixin ForwardGtkCairoCFunc!(._cairo_surface_create_similar);
-    +/
+    mixin ForwardGtkCairoCFunc!(.cairo_image_surface_get_height);
+    mixin ForwardGtkCairoCFunc!(.cairo_image_surface_get_width);
+    mixin ForwardGtkCairoCFunc!(.cairo_in_fill);
+    mixin ForwardGtkCairoCFunc!(.cairo_in_stroke);
+    mixin ForwardGtkCairoCFunc!(.cairo_line_to);
+    mixin ForwardGtkCairoCFunc!(.cairo_mask);
+    mixin ForwardGtkCairoCFunc!(.cairo_mask_surface);
+    mixin ForwardGtkCairoCFunc!(.cairo_matrix_init);
+    mixin ForwardGtkCairoCFunc!(.cairo_matrix_init_identity);
+    mixin ForwardGtkCairoCFunc!(.cairo_matrix_init_rotate);
+    mixin ForwardGtkCairoCFunc!(.cairo_matrix_init_scale);
+    mixin ForwardGtkCairoCFunc!(.cairo_matrix_init_translate);
+    mixin ForwardGtkCairoCFunc!(.cairo_matrix_invert);
+    mixin ForwardGtkCairoCFunc!(.cairo_matrix_multiply);
+    mixin ForwardGtkCairoCFunc!(.cairo_matrix_rotate);
+    mixin ForwardGtkCairoCFunc!(.cairo_matrix_scale);
+    mixin ForwardGtkCairoCFunc!(.cairo_matrix_transform_distance);
+    mixin ForwardGtkCairoCFunc!(.cairo_matrix_transform_point);
+    mixin ForwardGtkCairoCFunc!(.cairo_matrix_translate);
+    mixin ForwardGtkCairoCFunc!(.cairo_move_to);
+    mixin ForwardGtkCairoCFunc!(.cairo_new_path);
+    mixin ForwardGtkCairoCFunc!(.cairo_paint);
+    mixin ForwardGtkCairoCFunc!(.cairo_paint_with_alpha);
+    mixin ForwardGtkCairoCFunc!(.cairo_path_destroy);
+    mixin ForwardGtkCairoCFunc!(.cairo_pattern_add_color_stop_rgb);
+    mixin ForwardGtkCairoCFunc!(.cairo_pattern_add_color_stop_rgba);
+    mixin ForwardGtkCairoCFunc!(.cairo_pattern_create_for_surface);
+    mixin ForwardGtkCairoCFunc!(.cairo_pattern_create_linear);
+    mixin ForwardGtkCairoCFunc!(.cairo_pattern_create_radial);
+    mixin ForwardGtkCairoCFunc!(.cairo_pattern_destroy);
+    mixin ForwardGtkCairoCFunc!(.cairo_pattern_get_extend);
+    mixin ForwardGtkCairoCFunc!(.cairo_pattern_get_filter);
+    mixin ForwardGtkCairoCFunc!(.cairo_pattern_get_matrix);
+    mixin ForwardGtkCairoCFunc!(.cairo_pattern_reference);
+    mixin ForwardGtkCairoCFunc!(.cairo_pattern_set_extend);
+    mixin ForwardGtkCairoCFunc!(.cairo_pattern_set_filter);
+    mixin ForwardGtkCairoCFunc!(.cairo_pattern_set_matrix);
+    //mixin ForwardGtkCairoCFunc!(.cairo_pdf_surface_set_size);
+    //mixin ForwardGtkCairoCFunc!(.cairo_ps_surface_set_size);
+    mixin ForwardGtkCairoCFunc!(.cairo_rectangle);
+    mixin ForwardGtkCairoCFunc!(.cairo_reference);
+    mixin ForwardGtkCairoCFunc!(.cairo_rel_curve_to);
+    mixin ForwardGtkCairoCFunc!(.cairo_rel_line_to);
+    mixin ForwardGtkCairoCFunc!(.cairo_rel_move_to);
+    mixin ForwardGtkCairoCFunc!(.cairo_reset_clip);
+    mixin ForwardGtkCairoCFunc!(.cairo_restore);
+    mixin ForwardGtkCairoCFunc!(.cairo_rotate);
+    mixin ForwardGtkCairoCFunc!(.cairo_save);
+    mixin ForwardGtkCairoCFunc!(.cairo_scale);
+    mixin ForwardGtkCairoCFunc!(.cairo_select_font_face);
+    mixin ForwardGtkCairoCFunc!(.cairo_set_antialias);
+    mixin ForwardGtkCairoCFunc!(.cairo_set_dash);
+    mixin ForwardGtkCairoCFunc!(.cairo_set_fill_rule);
+    mixin ForwardGtkCairoCFunc!(.cairo_set_font_face);
+    mixin ForwardGtkCairoCFunc!(.cairo_set_font_matrix);
+    mixin ForwardGtkCairoCFunc!(.cairo_set_font_options);
+    mixin ForwardGtkCairoCFunc!(.cairo_set_font_size);
+    mixin ForwardGtkCairoCFunc!(.cairo_set_line_cap);
+    mixin ForwardGtkCairoCFunc!(.cairo_set_line_join);
+    mixin ForwardGtkCairoCFunc!(.cairo_set_line_width);
+    mixin ForwardGtkCairoCFunc!(.cairo_set_matrix);
+    mixin ForwardGtkCairoCFunc!(.cairo_set_miter_limit);
+    mixin ForwardGtkCairoCFunc!(.cairo_set_operator);
+    mixin ForwardGtkCairoCFunc!(.cairo_set_source);
+    mixin ForwardGtkCairoCFunc!(.cairo_set_source_rgb);
+    mixin ForwardGtkCairoCFunc!(.cairo_set_source_rgba);
+    mixin ForwardGtkCairoCFunc!(.cairo_set_source_surface);
+    mixin ForwardGtkCairoCFunc!(.cairo_set_tolerance);
+    mixin ForwardGtkCairoCFunc!(.cairo_show_glyphs);
+    mixin ForwardGtkCairoCFunc!(.cairo_show_page);
+    mixin ForwardGtkCairoCFunc!(.cairo_show_text);
+    mixin ForwardGtkCairoCFunc!(.cairo_status);
+    mixin ForwardGtkCairoCFunc!(.cairo_status_to_string);
+    mixin ForwardGtkCairoCFunc!(.cairo_stroke);
+    mixin ForwardGtkCairoCFunc!(.cairo_stroke_extents);
+    mixin ForwardGtkCairoCFunc!(.cairo_stroke_preserve);
+    mixin ForwardGtkCairoCFunc!(.cairo_surface_create_similar);
     mixin ForwardGtkCairoCFunc!(.cairo_surface_destroy);
-    /+
-    mixin ForwardGtkCairoCFunc!(._cairo_surface_finish);
-    mixin ForwardGtkCairoCFunc!(._cairo_surface_get_type);
-    mixin ForwardGtkCairoCFunc!(._cairo_surface_get_user_data);
-    mixin ForwardGtkCairoCFunc!(._cairo_surface_reference);
-    mixin ForwardGtkCairoCFunc!(._cairo_surface_set_device_offset);
-    mixin ForwardGtkCairoCFunc!(._cairo_surface_set_fallback_resolution);
-    mixin ForwardGtkCairoCFunc!(._cairo_surface_set_user_data);
-    mixin ForwardGtkCairoCFunc!(._cairo_text_extents);
-    mixin ForwardGtkCairoCFunc!(._cairo_text_path);
-    mixin ForwardGtkCairoCFunc!(._cairo_transform);
-    mixin ForwardGtkCairoCFunc!(._cairo_translate);
-    mixin ForwardGtkCairoCFunc!(._cairo_user_to_device);
-    mixin ForwardGtkCairoCFunc!(._cairo_user_to_device_distance);
+    mixin ForwardGtkCairoCFunc!(.cairo_surface_finish);
+    mixin ForwardGtkCairoCFunc!(.cairo_surface_get_type);
+    mixin ForwardGtkCairoCFunc!(.cairo_surface_get_user_data);
+    mixin ForwardGtkCairoCFunc!(.cairo_surface_reference);
+    mixin ForwardGtkCairoCFunc!(.cairo_surface_set_device_offset);
+    mixin ForwardGtkCairoCFunc!(.cairo_surface_set_fallback_resolution);
+    mixin ForwardGtkCairoCFunc!(.cairo_surface_set_user_data);
+    mixin ForwardGtkCairoCFunc!(.cairo_text_extents);
+    mixin ForwardGtkCairoCFunc!(.cairo_text_path);
+    mixin ForwardGtkCairoCFunc!(.cairo_transform);
+    mixin ForwardGtkCairoCFunc!(.cairo_translate);
+    mixin ForwardGtkCairoCFunc!(.cairo_user_to_device);
+    mixin ForwardGtkCairoCFunc!(.cairo_user_to_device_distance);
     mixin ForwardGtkCairoCFunc!(.cairo_version);
-    +/
     mixin ForwardGtkCairoCFunc!(.cairo_xlib_surface_create);
     /+
-    mixin ForwardGtkCairoCFunc!(._cairo_xlib_surface_create_for_bitmap);
-    mixin ForwardGtkCairoCFunc!(._cairo_xlib_surface_set_size);
+    mixin ForwardGtkCairoCFunc!(.cairo_xlib_surface_create_for_bitmap);
+    mixin ForwardGtkCairoCFunc!(.cairo_xlib_surface_set_size);
 +/
 }
--- a/dwt/internal/gtk/c/cairotypes.d	Mon Jan 07 08:07:46 2008 +0100
+++ b/dwt/internal/gtk/c/cairotypes.d	Mon Jan 07 09:11:15 2008 +0100
@@ -364,7 +364,11 @@
  * includes both headers and coordinates for each portion.
  * cairo_status_tstatus;
  */
-public struct cairo_path_t{}
+public struct cairo_path_t{
+    int status;
+    cairo_path_data_t * data;
+    int num_data;
+}
 // cairo_status_t status;
 // cairo-Paths.html
 // cairo_path_data_t *data;
@@ -544,5 +548,14 @@
 // void (*cairo_destroy_func_t) (void *data);
 public typedef extern(C) void  function (void*) cairo_destroy_func_t;
 
-// skipped union cairo_path_data_t
+union cairo_path_data_t{
+    struct {
+        int type;
+        int length;
+    }
+    struct {
+        double x;
+        double y;
+    }
+}
 
--- a/todo.txt	Mon Jan 07 08:07:46 2008 +0100
+++ b/todo.txt	Mon Jan 07 09:11:15 2008 +0100
@@ -25,7 +25,7 @@
 internal/SWTEventObject                // OK (java.util.EventObject)
 
 graphics/Color                         // OK
-graphics/Cursor
+graphics/Cursor                        // OK
 graphics/Device                        // OK
 graphics/DeviceData                    // OK (fld: debug->debugging)
 graphics/Drawable                      // OK
@@ -33,8 +33,8 @@
 graphics/FontData                      // OK
 graphics/FontMetrics                   // OK
 graphics/GC
-graphics/GCData
-graphics/GlyphMetrics
+graphics/GCData                        // OK
+graphics/GlyphMetrics                  // OK
 graphics/Image                         // OK
 graphics/ImageData                     // OK
 graphics/ImageDataLoader               // OK
@@ -43,9 +43,9 @@
 graphics/ImageLoaderListener           // OK
 graphics/LineAttributes                // OK
 graphics/PaletteData                   // OK
-graphics/Path
+graphics/Path                          // OK
 graphics/PathData                      // OK
-graphics/Pattern
+graphics/Pattern                       // OK
 graphics/Point                         // OK
 graphics/Rectangle                     // OK (meth union->makeUnion)
 graphics/Region                        // OK