From 2c834cb92f490610b4092d1ee911c1b198f8ee07 Mon Sep 17 00:00:00 2001 From: Nicola Fontana Date: Fri, 16 Oct 2009 14:39:09 +0200 Subject: [PATCH] [AdgPath] Added API to access last and over primitives Implemented adg_path_last_primitive() and adg_path_over_primitive() to get respectively the last and the previous the last primitives appended to an AdgPath. Modified the code accordling and let the default append method (adg_path_append()) do his job also when adding the result of an operation (such as a line for chamfers and an arc for fillets). The adg_path_over_primitive() is especially useful to access the primitive added by the forementioned operations. The _last version has been added only for completness. --- adg/adg-path-private.h | 1 + adg/adg-path.c | 93 +++++++++++++++++++++++++++++++++++--------------- adg/adg-path.h | 14 ++++---- 3 files changed, 74 insertions(+), 34 deletions(-) diff --git a/adg/adg-path-private.h b/adg/adg-path-private.h index 38640462..c8215737 100644 --- a/adg/adg-path-private.h +++ b/adg/adg-path-private.h @@ -58,6 +58,7 @@ struct _AdgPathPrivate { } cpml; CpmlPrimitive last; + CpmlPrimitive over; AdgOperation operation; }; diff --git a/adg/adg-path.c b/adg/adg-path.c index 5947ac89..67ca3e1e 100644 --- a/adg/adg-path.c +++ b/adg/adg-path.c @@ -85,12 +85,12 @@ static void do_operation (AdgPath *path, cairo_path_data_t *path_data); static void do_chamfer (AdgPath *path, - CpmlPrimitive *current); + AdgPrimitive *current); static void do_fillet (AdgPath *path, - CpmlPrimitive *current); -static gboolean is_convex (const CpmlPrimitive + AdgPrimitive *current); +static gboolean is_convex (const AdgPrimitive *primitive1, - const CpmlPrimitive + const AdgPrimitive *primitive2); @@ -584,7 +584,6 @@ adg_path_chamfer(AdgPath *path, gdouble delta1, gdouble delta2) * @path: an #AdgPath * @radius: the radius of the fillet * - * * A binary action that joins to primitives with an arc. * The first primitive involved is the current primitive, the second will * be the next primitive appended to @path after this call. The second @@ -601,6 +600,52 @@ adg_path_fillet(AdgPath *path, gdouble radius) return; } +/** + * adg_path_last_primitive: + * @path: an #AdgPath + * + * Gets the last primitive appended to @path. The returned struct + * is owned by @path and should not be freed or modified. + * + * Returns: a pointer to the last appended primitive or %NULL on errors + **/ +const AdgPrimitive * +adg_path_last_primitive(AdgPath *path) +{ + AdgPathPrivate *data; + + g_return_val_if_fail(ADG_IS_PATH(path), NULL); + + data = path->data; + + return &data->last; +} + +/** + * adg_path_over_primitive: + * @path: an #AdgPath + * + * Gets the primitive before the last one appended to @path. The + * "over" term comes from forth, where the %OVER operator works + * on the stack in the same way as adg_path_over_primitive() works + * on @path. The returned struct is owned by @path and should not + * be freed or modified. + * + * Returns: a pointer to the primitive before the last appended one + * or %NULL on errors + **/ +const AdgPrimitive * +adg_path_over_primitive(AdgPath *path) +{ + AdgPathPrivate *data; + + g_return_val_if_fail(ADG_IS_PATH(path), NULL); + + data = path->data; + + return &data->over; +} + static void clear(AdgModel *model) @@ -675,6 +720,9 @@ append_primitive(AdgPath *path, AdgPrimitive *current) path_data = (cairo_path_data_t *) (data->cpml.array)->data + (data->cpml.array)->len - length; + /* Store the over primitive */ + memcpy(&data->over, &data->last, sizeof(AdgPrimitive)); + /* Set the last primitive for subsequent binary operations */ data->last.org = data->cp_is_valid ? path_data - 1 : NULL; data->last.segment = NULL; @@ -797,8 +845,8 @@ do_operation(AdgPath *path, cairo_path_data_t *path_data) { AdgPathPrivate *data; AdgAction action; - CpmlSegment segment; - CpmlPrimitive current; + AdgSegment segment; + AdgPrimitive current; cairo_path_data_t current_org; data = path->data; @@ -835,14 +883,13 @@ do_operation(AdgPath *path, cairo_path_data_t *path_data) } static void -do_chamfer(AdgPath *path, CpmlPrimitive *current) +do_chamfer(AdgPath *path, AdgPrimitive *current) { AdgPathPrivate *data; - CpmlPrimitive *last; + AdgPrimitive *last; gdouble delta1, delta2; gdouble len1, len2; AdgPair pair; - cairo_path_data_t line[2]; data = path->data; last = &data->last; @@ -873,23 +920,17 @@ do_chamfer(AdgPath *path, CpmlPrimitive *current) cpml_pair_to_cairo(&pair, cpml_primitive_get_point(current, 0)); /* Add the chamfer line */ - line[0].header.type = CAIRO_PATH_LINE_TO; - line[0].header.length = 2; - line[1].point.x = pair.x; - line[1].point.y = pair.y; - data->cpml.array = g_array_append_vals(data->cpml.array, line, 2); - data->operation.action = ADG_ACTION_NONE; + adg_path_append(path, CAIRO_PATH_LINE_TO, &pair); } static void -do_fillet(AdgPath *path, CpmlPrimitive *current) +do_fillet(AdgPath *path, AdgPrimitive *current) { AdgPathPrivate *data; - CpmlPrimitive *last, *current_dup, *last_dup; + AdgPrimitive *last, *current_dup, *last_dup; gdouble radius, offset, pos; AdgPair center, vector, p[3]; - cairo_path_data_t arc[3]; data = path->data; last = &data->last; @@ -938,21 +979,19 @@ do_fillet(AdgPath *path, CpmlPrimitive *current) g_free(current_dup); g_free(last_dup); - /* Modify the end point of the last primitive */ + /* Change the end point of the last primitive */ cpml_pair_to_cairo(&p[0], cpml_primitive_get_point(last, -1)); - /* Add the fillet arc */ - arc[0].header.type = CAIRO_PATH_ARC_TO; - arc[0].header.length = 3; - cpml_pair_to_cairo(&p[1], &arc[1]); - cpml_pair_to_cairo(&p[2], &arc[2]); - data->cpml.array = g_array_append_vals(data->cpml.array, arc, 3); + /* Change the start point of the current primitive */ + cpml_pair_to_cairo(&p[2], cpml_primitive_get_point(current, 0)); + /* Add the fillet arc */ data->operation.action = ADG_ACTION_NONE; + adg_path_append(path, CAIRO_PATH_ARC_TO, &p[1], &p[2]); } static gboolean -is_convex(const CpmlPrimitive *primitive1, const CpmlPrimitive *primitive2) +is_convex(const AdgPrimitive *primitive1, const AdgPrimitive *primitive2) { CpmlVector v1, v2; gdouble angle1, angle2; diff --git a/adg/adg-path.h b/adg/adg-path.h index cad261ae..8ea81eef 100644 --- a/adg/adg-path.h +++ b/adg/adg-path.h @@ -24,7 +24,6 @@ #include #include #include -#include G_BEGIN_DECLS @@ -58,19 +57,16 @@ const AdgPair * adg_path_current_point (AdgPath *path); gboolean adg_path_has_current_point (AdgPath *path); void adg_path_append (AdgPath *path, - cairo_path_data_type_t - type, + cairo_path_data_type_t type, ...); void adg_path_append_valist (AdgPath *path, - cairo_path_data_type_t - type, + cairo_path_data_type_t type, va_list var_args); void adg_path_append_primitive (AdgPath *path, const AdgPrimitive *primitive); void adg_path_append_segment (AdgPath *path, - const AdgSegment - *segment); + const AdgSegment *segment); void adg_path_append_cairo_path (AdgPath *path, const cairo_path_t *cairo_path); @@ -105,6 +101,10 @@ void adg_path_chamfer (AdgPath *path, gdouble delta2); void adg_path_fillet (AdgPath *path, gdouble radius); +const AdgPrimitive * + adg_path_last_primitive (AdgPath *path); +const AdgPrimitive * + adg_path_over_primitive (AdgPath *path); G_END_DECLS -- 2.11.4.GIT