From ef7068109bd60ccb9bb6b1c0fbc0be0cf560f3a7 Mon Sep 17 00:00:00 2001 From: Nicola Fontana Date: Wed, 14 Oct 2009 01:21:23 +0200 Subject: [PATCH] [AdgPoint] First implementation AdgPoint is an AdgPair on steroid, adding linking feature to a named pair in any AdgModel instances. This will make the transition from explicit coordinates to named pairs transparent, as AdgPoint supports both. --- adg/Makefile.am | 8 +- adg/adg-point.c | 267 ++++++++++++++++++++++++++++++++++++++++++++++++++ adg/adg-point.h | 57 +++++++++++ adg/adg.h.in | 1 + docs/adg/adg-docs.xml | 25 +++-- 5 files changed, 346 insertions(+), 12 deletions(-) create mode 100644 adg/adg-point.c create mode 100644 adg/adg-point.h diff --git a/adg/Makefile.am b/adg/Makefile.am index 3403f859..31d70087 100644 --- a/adg/Makefile.am +++ b/adg/Makefile.am @@ -14,6 +14,7 @@ h_sources= adg-adim.h \ adg-dress-builtins.h \ adg-edges.h \ adg-entity.h \ + adg-fill-style.h \ adg-font-style.h \ adg-hatch.h \ adg-ldim.h \ @@ -24,7 +25,7 @@ h_sources= adg-adim.h \ adg-pair.h \ adg-path.h \ adg-pattern.h \ - adg-fill-style.h \ + adg-point.h \ adg-primitive.h \ adg-rdim.h \ adg-ruled-fill.h \ @@ -49,6 +50,7 @@ private_h_sources= adg-adim-private.h \ adg-edges-private.h \ adg-entity-private.h \ adg-enums.h \ + adg-fill-style-private.h \ adg-font-style-private.h \ adg-hatch-private.h \ adg-intl.h \ @@ -57,7 +59,6 @@ private_h_sources= adg-adim-private.h \ adg-marker-private.h \ adg-model-private.h \ adg-path-private.h \ - adg-fill-style-private.h \ adg-rdim-private.h \ adg-ruled-fill-private.h \ adg-stroke-private.h \ @@ -77,6 +78,7 @@ c_sources= adg-adim.c \ adg-edges.c \ adg-entity.c \ adg-enums.c \ + adg-fill-style.c \ adg-font-style.c \ adg-hatch.c \ adg-ldim.c \ @@ -87,7 +89,7 @@ c_sources= adg-adim.c \ adg-pair.c \ adg-path.c \ adg-pattern.c \ - adg-fill-style.c \ + adg-point.c \ adg-primitive.c \ adg-rdim.c \ adg-ruled-fill.c \ diff --git a/adg/adg-point.c b/adg/adg-point.c new file mode 100644 index 00000000..be24f7fb --- /dev/null +++ b/adg/adg-point.c @@ -0,0 +1,267 @@ +/* ADG - Automatic Drawing Generation + * Copyright (C) 2007,2008,2009 Nicola Fontana + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + + +/** + * SECTION:adg-point + * @Section_Id:AdgPoint + * @title: AdgPoint + * @short_description: A struct holding x, y coordinates + * (either named or explicit) + * + * AdgPoint is an opaque structure that manages 2D coordinates, either + * set explicitely throught adg_point_set() and adg_point_set_explicit() + * or taken from a model with adg_point_set_from_model(). It can be + * thought as an #AdgPair on steroid, because it adds named pair + * support to a simple pairs, and thus enabling coordinates depending + * on #AdgModel instances. + **/ + +/** + * ADG_POINT_PAIR: + * @point: an #AdgPoint + * + * #AdgPoint is an evolution of the pair concept, but internally the + * relevant data is still kept by an #AdgPair struct. This macro + * gets this struct. Being declared at the start of the #AdgPoint + * struct, it'd suffice to cast the point to an #AdgPair too. + * + * Returns: the pair of @point + **/ + +/** + * AdgPoint: + * + * This is an opaque struct: all its fields are privates. + **/ + + +#include "adg-point.h" + +#include + + +struct _AdgPoint { + AdgPair pair; + AdgModel *model; + gchar *name; +}; + +GType +adg_point_get_type(void) +{ + static int type = 0; + + if (G_UNLIKELY(type == 0)) + type = g_boxed_type_register_static("AdgPoint", + (GBoxedCopyFunc) adg_point_dup, + (GBoxedFreeFunc) adg_point_destroy); + + return type; +} + +/** + * adg_point_copy: + * @point: an #AdgPoint + * @src: the source point to copy + * + * Copies @src into @point. + * + * Returns: @point + **/ +AdgPoint * +adg_point_copy(AdgPoint *point, const AdgPoint *src) +{ + g_return_val_if_fail(point != NULL, NULL); + g_return_val_if_fail(src != NULL, NULL); + + if (src->model != NULL) + g_object_ref(src->model); + + if (point->model != NULL) + g_object_unref(point->model); + + return memcpy(point, src, sizeof(AdgPoint)); +} + +/** + * adg_point_dup: + * @point: an #AdgPoint structure + * + * Duplicates @point. + * + * Returns: the duplicated #AdgPoint struct or %NULL on errors + **/ +AdgPoint * +adg_point_dup(const AdgPoint *point) +{ + g_return_val_if_fail(point != NULL, NULL); + + if (point->model != NULL) + g_object_ref(point->model); + + return g_memdup(point, sizeof(AdgPoint)); +} + +/** + * adg_point_new: + * + * Creates a new empty #AdgPoint. The returned pointer + * should be freed with adg_point_destroy() when no longer needed. + * + * Returns: a newly created #AdgPoint + **/ +AdgPoint * +adg_point_new(void) +{ + return g_new0(AdgPoint, 1); +} + +/** + * adg_point_destroy: + * @point: an #AdgPoint + * + * Destroys the @point instance, unreferencing the internal model if + * @point is linked to a named pair. + **/ +void +adg_point_destroy(AdgPoint *point) +{ + g_return_if_fail(point != NULL); + + adg_point_set_from_model(point, NULL, NULL); + + g_free(point); +} + +/** + * adg_point_set: + * @point: an #AdgPoint + * @pair: the #AdgPair to use + * + * Sets an explicit pair in @point by using the given @pair. If + * @point was linked to a named pair in a model, this link is + * dropped before setting the pair. + **/ +void +adg_point_set(AdgPoint *point, const AdgPair *pair) +{ + g_return_if_fail(point != NULL); + g_return_if_fail(pair != NULL); + + adg_point_set_explicit(point, pair->x, pair->y); +} + +/** + * adg_point_set_explicit: + * @point: an #AdgPoint + * @x: the x coordinate of the point + * @y: the y coordinate of the point + * + * Works in the same way of adg_point_set() but accept direct numbers + * instead of an #AdgPair structure. + **/ +void +adg_point_set_explicit(AdgPoint *point, gdouble x, gdouble y) +{ + g_return_if_fail(point != NULL); + + /* Unlink the named pair dependency, if any */ + adg_point_set_from_model(point, NULL, NULL); + + point->pair.x = x; + point->pair.y = y; +} + +/** + * adg_point_set_from_model: + * @point: an #AdgPair + * @model: the #AdgModel + * @name: the id of a named pair in @model + * + * Links the @name named pair of @model to @point, so any subsequent + * call to adg_point_update() will read the named pair content. A + * new reference is added to @model while the previous model (if any) + * is unreferenced. + * + * It is allowed to use %NULL as @model, in which case the link + * between @point and the named pair is dropped. + **/ +void +adg_point_set_from_model(AdgPoint *point, AdgModel *model, const gchar *name) +{ + g_return_if_fail(point != NULL); + + /* Check if unlinking a yet unlinked point */ + if (model == NULL && point->model == NULL) + return; + + /* Ensure the name is not NULL if the model is specified */ + if (model != NULL) { + g_return_if_fail(name != NULL); + } + + /* Check if the named pair is different from the old one */ + if (model == point->model && strcmp(point->name, name) == 0) + return; + + if (model != NULL) + g_object_ref(model); + + if (point->model != NULL) { + /* Remove the old named pair */ + g_object_unref(point->model); + g_free(point->name); + point->model = NULL; + point->name = NULL; + } + + if (model != NULL) { + /* Set the new named pair */ + point->model = model; + point->name = g_strdup(name); + } + + adg_point_update(point); +} + +/** + * adg_point_update: + * @point: an #AdgPoint + * + * Updates the pair of @point. If @point is an explicit pair (either + * if set with adg_point_set() or adg_point_set_explicit()), no action + * is taken. If @point is linked to a named pair, instead, the internal + * pair is updated with the value returned by adg_model_get_named_pair(). + **/ +void +adg_point_update(AdgPoint *point) +{ + const AdgPair *pair; + + g_return_if_fail(point != NULL); + + /* A point with explicit coordinates does not need to be updated */ + if (point->model == NULL) + return; + + pair = adg_model_get_named_pair(point->model, point->name); + + cpml_pair_copy(&point->pair, pair); +} diff --git a/adg/adg-point.h b/adg/adg-point.h new file mode 100644 index 00000000..793cefa0 --- /dev/null +++ b/adg/adg-point.h @@ -0,0 +1,57 @@ +/* ADG - Automatic Drawing Generation + * Copyright (C) 2007,2008,2009 Nicola Fontana + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + + +#ifndef __ADG_POINT_H__ +#define __ADG_POINT_H__ + +#include +#include + + +G_BEGIN_DECLS + +#define ADG_TYPE_POINT (adg_point_get_type()) +#define ADG_POINT_PAIR(point) ((AdgPair *) (point)) + + +typedef struct _AdgPoint AdgPoint; + + +GType adg_point_get_type (void) G_GNUC_CONST; + +AdgPoint * adg_point_copy (AdgPoint *point, + const AdgPoint *src); +AdgPoint * adg_point_new (void); +AdgPoint * adg_point_dup (const AdgPoint *point); +void adg_point_destroy (AdgPoint *point); +void adg_point_set (AdgPoint *point, + const AdgPair *pair); +void adg_point_set_explicit (AdgPoint *point, + gdouble x, + gdouble y); +void adg_point_set_from_model(AdgPoint *point, + AdgModel *model, + const gchar *name); +void adg_point_update (AdgPoint *point); + +G_END_DECLS + + +#endif /* __ADG_POINT_H__ */ diff --git a/adg/adg.h.in b/adg/adg.h.in index 27111f22..e553d92e 100644 --- a/adg/adg.h.in +++ b/adg/adg.h.in @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include diff --git a/docs/adg/adg-docs.xml b/docs/adg/adg-docs.xml index df9f6222..5a0ae6c3 100644 --- a/docs/adg/adg-docs.xml +++ b/docs/adg/adg-docs.xml @@ -16,8 +16,9 @@ - GBoxed foreign types + GBoxed types + @@ -38,14 +39,15 @@ - - - - - - Markers - - + + Stock entities + + + + + + Special entities + Quoting @@ -54,6 +56,11 @@ + + Markers + + + -- 2.11.4.GIT