summaryrefslogtreecommitdiff
path: root/src/cairo-path-data.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cairo-path-data.c')
-rw-r--r--src/cairo-path-data.c111
1 files changed, 103 insertions, 8 deletions
diff --git a/src/cairo-path-data.c b/src/cairo-path-data.c
index 95fc3bb26..519c76315 100644
--- a/src/cairo-path-data.c
+++ b/src/cairo-path-data.c
@@ -37,8 +37,8 @@
#include "cairo-path-fixed-private.h"
#include "cairo-gstate-private.h"
-cairo_path_t
-_cairo_path_nil = { NULL, 0 };
+static cairo_path_t
+cairo_path_nil = { CAIRO_STATUS_NO_MEMORY, NULL, 0 };
/* Closure for path interpretation. */
typedef struct cairo_path_data_count {
@@ -105,14 +105,18 @@ _cpdc_curve_to_flatten (void *closure,
status = _cairo_spline_decompose (&spline, cpdc->tolerance);
if (status)
- return status;
+ goto out;
for (i=1; i < spline.num_points; i++)
_cpdc_line_to (cpdc, &spline.points[i]);
cpdc->current_point = *p3;
- return CAIRO_STATUS_SUCCESS;
+ status = CAIRO_STATUS_SUCCESS;
+
+ out:
+ _cairo_spline_fini (&spline);
+ return status;
}
static cairo_status_t
@@ -276,14 +280,18 @@ _cpdp_curve_to_flatten (void *closure,
status = _cairo_spline_decompose (&spline, cpdp->gstate->tolerance);
if (status)
- return status;
+ goto out;
for (i=1; i < spline.num_points; i++)
_cpdp_line_to (cpdp, &spline.points[i]);
cpdp->current_point = *p3;
- return CAIRO_STATUS_SUCCESS;
+ status = CAIRO_STATUS_SUCCESS;
+
+ out:
+ _cairo_spline_fini (&spline);
+ return status;
}
static cairo_status_t
@@ -339,7 +347,7 @@ _cairo_path_data_create_real (cairo_path_fixed_t *path_fixed,
path = malloc (sizeof (cairo_path_t));
if (path == NULL)
- return &_cairo_path_nil;
+ return &cairo_path_nil;
path->num_data = _cairo_path_data_count (path, path_fixed,
gstate->tolerance, flatten);
@@ -347,23 +355,56 @@ _cairo_path_data_create_real (cairo_path_fixed_t *path_fixed,
path->data = malloc (path->num_data * sizeof (cairo_path_data_t));
if (path->data == NULL) {
free (path);
- return &_cairo_path_nil;
+ return &cairo_path_nil;
}
+ path->status = CAIRO_STATUS_SUCCESS;
+
_cairo_path_data_populate (path, path_fixed,
gstate, flatten);
return path;
}
+/**
+ * cairo_path_destroy:
+ * @path: a path to destroy which was previously returned by either
+ * cairo_copy_path or cairo_copy_path_flat.
+ *
+ * Immediately releases all memory associated with @path. After a call
+ * to cairo_path_destroy() the @path pointer is no longer valid and
+ * should not be used further.
+ *
+ * NOTE: cairo_path_destroy function should only be called with a
+ * pointer to a #cairo_path_t returned by a cairo function. Any path
+ * that is created manually (ie. outside of cairo) should be destroyed
+ * manually as well.
+ **/
void
cairo_path_destroy (cairo_path_t *path)
{
+ if (path == NULL || path == &cairo_path_nil)
+ return;
+
free (path->data);
path->num_data = 0;
free (path);
}
+/**
+ * _cairo_path_data_create:
+ * @path: a fixed-point, device-space path to be converted and copied
+ * @gstate: the current graphics state
+ *
+ * Creates a user-space #cairo_path_t copy of the given device-space
+ * @path. The @gstate parameter provides the inverse CTM for the
+ * conversion.
+ *
+ * Return value: the new copy of the path. If there is insufficient
+ * memory a pointer to a special static cairo_path_nil will be
+ * returned instead with status==CAIRO_STATUS_NO_MEMORY and
+ * data==NULL.
+ **/
cairo_path_t *
_cairo_path_data_create (cairo_path_fixed_t *path,
cairo_gstate_t *gstate)
@@ -371,6 +412,21 @@ _cairo_path_data_create (cairo_path_fixed_t *path,
return _cairo_path_data_create_real (path, gstate, FALSE);
}
+/**
+ * _cairo_path_data_create_flat:
+ * @path: a fixed-point, device-space path to be flattened, converted and copied
+ * @gstate: the current graphics state
+ *
+ * Creates a flattened, user-space #cairo_path_t copy of the given
+ * device-space @path. The @gstate parameter provide the inverse CTM
+ * for the conversion, as well as the tolerance value to control the
+ * accuracy of the flattening.
+ *
+ * Return value: the flattened copy of the path. If there is insufficient
+ * memory a pointer to a special static cairo_path_nil will be
+ * returned instead with status==CAIRO_STATUS_NO_MEMORY and
+ * data==NULL.
+ **/
cairo_path_t *
_cairo_path_data_create_flat (cairo_path_fixed_t *path,
cairo_gstate_t *gstate)
@@ -378,6 +434,45 @@ _cairo_path_data_create_flat (cairo_path_fixed_t *path,
return _cairo_path_data_create_real (path, gstate, TRUE);
}
+/**
+ * _cairo_path_data_create_in_error:
+ * @status: an error status
+ *
+ * Create an empty #cairo_path_t object to hold an error status. This
+ * is useful for propagating status values from an existing object to
+ * a new #cairo_path_t.
+ *
+ * Return value: a #cairo_path_t object with status of @status, NULL
+ * data, and 0 num_data. If there is insufficient memory a pointer to
+ * a special static cairo_path_nil will be returned instead with
+ * status==CAIRO_STATUS_NO_MEMORY rather than @status.
+ **/
+cairo_path_t *
+_cairo_path_data_create_in_error (cairo_status_t status)
+{
+ cairo_path_t *path;
+
+ path = malloc (sizeof (cairo_path_t));
+ if (path == NULL)
+ return &cairo_path_nil;
+
+ path->status = status;
+ path->data = NULL;
+ path->num_data = 0;
+
+ return path;
+}
+
+/**
+ * _cairo_path_data_append_to_context:
+ * @path: the path data to be appended
+ * @cr: a cairo context
+ *
+ * Append @path to the current path within @cr.
+ *
+ * Return value: CAIRO_STATUS_INVALID_PATH_DATA if the data in @path
+ * is invalid, and CAIRO_STATUS_SUCCESS otherwise.
+ **/
cairo_status_t
_cairo_path_data_append_to_context (cairo_path_t *path,
cairo_t *cr)