/*******************************************************************************
 * Copyright (c) 2000, 2016 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
 *******************************************************************************/
package org.eclipse.swt.graphics;

import org.eclipse.swt.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.cairo.*;

/**
 * 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>
 *
 * @see <a href="http://www.eclipse.org/swt/snippets/#path">Path, Pattern snippets</a>
 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: GraphicsExample</a>
 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
 *
 * @since 3.1
 */
public class Path extends 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>
	 *
	 * @noreference This field is not intended to be referenced by clients.
	 */
	public long /*int*/ handle;

	boolean 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>
 * <p>
 * You must dispose the path when it is no longer required.
 * </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 Path (Device device) {
	super(device);
	long /*int*/ 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);
	init();
}

/**
 * Constructs a new Path that is a copy of <code>path</code>. If
 * <code>flatness</code> is less than or equal to zero, an unflatten
 * copy of the path is created. Otherwise, it specifies the maximum
 * error between the path and its flatten copy. Smaller numbers give
 * better approximation.
 * <p>
 * This operation requires the operating system's advanced
 * graphics subsystem which may not be available on some
 * platforms.
 * </p>
 * <p>
 * You must dispose the path when it is no longer required.
 * </p>
 *
 * @param device the device on which to allocate the path
 * @param path the path to make a copy
 * @param flatness the flatness value
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the device is null and there is no current device</li>
 *    <li>ERROR_NULL_ARGUMENT - if the path is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the path has been disposed</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()
 * @since 3.4
 */
public Path (Device device, Path path, float flatness) {
	super(device);
	if (path == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (path.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	long /*int*/ 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);
	long /*int*/ copy;
	flatness = Math.max(0, flatness);
	if (flatness == 0) {
		copy = Cairo.cairo_copy_path(path.handle);
	} else {
		double tolerance = Cairo.cairo_get_tolerance(path.handle);
		Cairo.cairo_set_tolerance(path.handle, flatness);
		copy = Cairo.cairo_copy_path_flat(path.handle);
		Cairo.cairo_set_tolerance(path.handle, tolerance);
	}
	if (copy == 0) {
		Cairo.cairo_destroy(handle);
		SWT.error(SWT.ERROR_NO_HANDLES);
	}
	Cairo.cairo_append_path(handle, copy);
	Cairo.cairo_path_destroy(copy);
	init();
}

/**
 * Constructs a new Path with the specified PathData.
 * <p>
 * This operation requires the operating system's advanced
 * graphics subsystem which may not be available on some
 * platforms.
 * </p>
 * <p>
 * You must dispose the path when it is no longer required.
 * </p>
 *
 * @param device the device on which to allocate the path
 * @param data the data for the path
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the device is null and there is no current device</li>
 *    <li>ERROR_NULL_ARGUMENT - if the data is null</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()
 * @since 3.4
 */
public Path (Device device, PathData data) {
	this(device);
	if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	init(data);
}

/**
 * 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);
	x = DPIUtil.autoScaleUp(x);
	y = DPIUtil.autoScaleUp(y);
	width = DPIUtil.autoScaleUp(width);
	height = DPIUtil.autoScaleUp(height);
	addArcInPixels(x, y, width, height, startAngle, arcAngle);
}

void addArcInPixels(float x, float y, float width, float height, float startAngle, float arcAngle) {
	moved = true;
	if (width == height) {
		float angle = -startAngle * (float)Math.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) * (float)Math.PI / 180);
		} else {
			Cairo.cairo_arc(handle, x + width / 2f, y + height / 2f, width / 2f, angle, -(startAngle + arcAngle) * (float)Math.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 * (float)Math.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) * (float)Math.PI / 180);
		} else {
			Cairo.cairo_arc(handle, 0, 0, 1, angle, -(startAngle + arcAngle) * (float)Math.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 == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (path.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
	moved = false;
	long /*int*/ 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);
	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);
	x = DPIUtil.autoScaleUp(x);
	y = DPIUtil.autoScaleUp(y);
	width = DPIUtil.autoScaleUp(width);
	height = DPIUtil.autoScaleUp(height);
	addRectangleInPixels(x, y, width, height);
}

void addRectangleInPixels(float x, float y, float width, float height) {
	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(String string, 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);
	x = DPIUtil.autoScaleUp(x);
	y = DPIUtil.autoScaleUp(y);
	// Scale up the font
	FontData fd = font.getFontData()[0];
	fd.setHeight(DPIUtil.autoScaleUp(fd.getHeight()));
	Font scaledFont = new Font(font.getDevice(), fd);
	addStringInPixels(string, x, y, scaledFont);
	scaledFont.dispose(); // Dispose the scaled up font
}
void addStringInPixels(String string, float x, float y, Font font) {
	moved = false;
	GC.addCairoString(handle, string, 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 boolean contains(float x, float y, GC gc, boolean 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);
	x = DPIUtil.autoScaleUp(x);
	y = DPIUtil.autoScaleUp(y);
	return containsInPixels(x, y, gc, outline);
}
boolean containsInPixels(float x, float y, GC gc, boolean outline) {
	//TODO - see Windows
	gc.initCairo();
	gc.checkGC(GC.LINE_CAP | GC.LINE_JOIN | GC.LINE_STYLE | GC.LINE_WIDTH);
	boolean result = false;
	long /*int*/ cairo = gc.data.cairo;
	long /*int*/ 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 {
		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);
	cx1 = DPIUtil.autoScaleUp(cx1);
	cy1 = DPIUtil.autoScaleUp(cy1);
	cx2 = DPIUtil.autoScaleUp(cx2);
	cy2 = DPIUtil.autoScaleUp(cy2);
	x = DPIUtil.autoScaleUp(x);
	y = DPIUtil.autoScaleUp(y);
	cubicToInPixels(cx1, cy1, cx2, cy2, x, y);
}
void cubicToInPixels(float cx1, float cy1, float cx2, float cy2, float x, float y) {
	if (!moved) {
		double[] currentX = new double[1], currentY = new double[1];
		Cairo.cairo_get_current_point(handle, currentX, currentY);
		Cairo.cairo_move_to(handle, currentX[0], currentY[0]);
		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);
	getBoundsInPixels(bounds);
	for (int i = 0; i < bounds.length; i++) {
		bounds [i] = DPIUtil.autoScaleDown(bounds[i]);
	}
}
void getBoundsInPixels(float[] bounds) {
	long /*int*/ 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) {
		minX = minY = Double.POSITIVE_INFINITY;
		maxX = maxY = Double.NEGATIVE_INFINITY;
		int i = 0;
		double[] points = new double[6];
		cairo_path_data_t data = new cairo_path_data_t();
		while (i < path.num_data) {
			long /*int*/ 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);
}

/**
 * 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);
	getCurrentPointInPixels(point);
	for (int i = 0; i < point.length; i++) {
		point [i] = DPIUtil.autoScaleDown(point[i]);
	}
}

void getCurrentPointInPixels(float[] point) {
	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_get_current_point(handle, x, y);
	point[0] = (float)x[0];
	point[1] = (float)y[0];
}

/**
 * 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);
	PathData result = getPathDataInPixels();
	result.points = DPIUtil.autoScaleDown(result.points);
	return result;
}

PathData getPathDataInPixels() {
	long /*int*/ 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) {
			long /*int*/ 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 = 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);
	x = DPIUtil.autoScaleUp(x);
	y = DPIUtil.autoScaleUp(y);
	lineToInPixels(x, y);
}
void lineToInPixels(float x, float y) {
	if (!moved) {
		double[] currentX = new double[1], currentY = new double[1];
		Cairo.cairo_get_current_point(handle, currentX, currentY);
		Cairo.cairo_move_to(handle, currentX[0], currentY[0]);
		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);
	x = DPIUtil.autoScaleUp(x);
	y = DPIUtil.autoScaleUp(y);
	moveToInPixels(x, y);
}
void moveToInPixels(float x, float y) {
	/*
	* 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);
	x = DPIUtil.autoScaleUp(x);
	y = DPIUtil.autoScaleUp(y);
	cx = DPIUtil.autoScaleUp(cx);
	cy = DPIUtil.autoScaleUp(cy);
	quadToInPixels(cx, cy, x, y);
}
void quadToInPixels(float cx, float cy, float x, float y) {
	double[] currentX = new double[1], currentY = new double[1];
	Cairo.cairo_get_current_point(handle, currentX, currentY);
	if (!moved) {
		Cairo.cairo_move_to(handle, currentX[0], currentY[0]);
		moved = true;
	}
	float x0 = (float)currentX[0];
	float y0 = (float)currentY[0];
	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;
}

@Override
void destroy() {
	Cairo.cairo_destroy(handle);
	handle = 0;
}

void init(PathData data) {
	byte[] types = data.types;
	float[] points = data.points;
	for (int i = 0, j = 0; i < types.length; i++) {
		switch (types[i]) {
			case SWT.PATH_MOVE_TO:
				moveTo(points[j++], points[j++]);
				break;
			case SWT.PATH_LINE_TO:
				lineTo(points[j++], points[j++]);
				break;
			case SWT.PATH_CUBIC_TO:
				cubicTo(points[j++], points[j++], points[j++], points[j++], points[j++], points[j++]);
				break;
			case SWT.PATH_QUAD_TO:
				quadTo(points[j++], points[j++], points[j++], points[j++]);
				break;
			case SWT.PATH_CLOSE:
				close();
				break;
			default:
				dispose();
				SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		}
	}
}

/**
 * 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 (except {@link #dispose()}) using the Path.
 *
 * @return <code>true</code> when the Path is disposed, and <code>false</code> otherwise
 */
@Override
public boolean isDisposed() {
	return handle == 0;
}

/**
 * Returns a string containing a concise, human-readable
 * description of the receiver.
 *
 * @return a string representation of the receiver
 */
@Override
public String toString() {
	if (isDisposed()) return "Path {*DISPOSED*}";
	return "Path {" + handle + "}";
}

}
