[dia] path: handle special cases of combinations w/o crossing
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] path: handle special cases of combinations w/o crossing
- Date: Sun, 14 Sep 2014 12:30:24 +0000 (UTC)
commit 7546391a16212dfadc514f353712e04618df4928
Author: Hans Breuer <hans breuer org>
Date: Tue Sep 9 21:25:56 2014 +0200
path: handle special cases of combinations w/o crossing
- path_combine(): implement the respective !crossing branch
- create_standard_path_from_list(): may return empty now
- _combine_to_path_callback(): an empty result is like a delete
Also fix transaction point position.
app/disp_callbacks.c | 13 ++++++----
lib/diapathrenderer.c | 11 ++++-----
lib/path-math.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 72 insertions(+), 13 deletions(-)
---
diff --git a/app/disp_callbacks.c b/app/disp_callbacks.c
index 62f06dc..8255566 100644
--- a/app/disp_callbacks.c
+++ b/app/disp_callbacks.c
@@ -238,15 +238,18 @@ _combine_to_path_callback (GtkAction *action, gpointer data)
(change->apply)(change, dia);
/* add the new object with undo */
undo_insert_objects(dia, g_list_prepend(NULL, obj), 1);
- undo_set_transactionpoint(ddisp->diagram->undo);
-
diagram_add_object (dia, obj);
diagram_select(dia, obj);
+ undo_set_transactionpoint(ddisp->diagram->undo);
object_add_updates(obj, dia);
-
- ddisplay_do_update_menu_sensitivity(ddisp);
- diagram_flush(dia);
+ } else {
+ /* path combination result is empty, this is just a delete */
+ Change *change = undo_delete_objects_children(ddisp->diagram, cut_list);
+ (change->apply)(change, ddisp->diagram);
+ undo_set_transactionpoint(ddisp->diagram->undo);
}
+ ddisplay_do_update_menu_sensitivity(ddisp);
+ diagram_flush(dia);
g_list_free (cut_list);
}
static void
diff --git a/lib/diapathrenderer.c b/lib/diapathrenderer.c
index ebc5e40..71616a1 100644
--- a/lib/diapathrenderer.c
+++ b/lib/diapathrenderer.c
@@ -874,12 +874,11 @@ create_standard_path_from_list (GList *objects,
}
if (p1 && p2) {
GArray *combined = path_combine (p1, p2, mode);
- if (combined) {
- g_array_free (p1, TRUE);
- p1 = combined;
- g_array_free (p2, TRUE);
- p2 = NULL;
- }
+ /* combined == NULL is just passed on */
+ g_array_free (p1, TRUE);
+ p1 = combined;
+ g_array_free (p2, TRUE);
+ p2 = NULL;
} else {
p1 = p2;
p2 = NULL;
diff --git a/lib/path-math.c b/lib/path-math.c
index a9bef7f..df4b292 100644
--- a/lib/path-math.c
+++ b/lib/path-math.c
@@ -302,6 +302,13 @@ struct _Split {
GArray *path; /*!< subpath copy */
};
+/*!
+ * \brief Extract splits from crossing
+ *
+ * Crossing is the array of Intersection which contains split information
+ * from crossing between two paths. This function separates the
+ * information into splits specific to a single path.
+ */
static GArray *
_extract_splits (const GArray *crossing, gboolean one)
{
@@ -619,8 +626,8 @@ _make_path0 (GArray *one, /*!< array<BezierSegment> from first path */
for (i = 0; i < segs->len; ++i) {
BezierSegment *seg = &g_array_index (segs, BezierSegment, i);
/* every split starts with a move-to */
- if ( isp < splits->len
- && 0
+ if ( splits
+ && isp < splits->len
&& i == g_array_index (splits, Split, isp).seg
&& g_array_index (result, BezPoint, result->len - 1).type != BEZ_MOVE_TO) {
bp.type = BEZ_MOVE_TO;
@@ -727,6 +734,16 @@ _make_path (GArray *one, /*!< array<BezierSegment> from first path */
return result;
}
+static GArray *
+_path_copy (const GArray *p)
+{
+ GArray *result = g_array_new (FALSE, FALSE, sizeof(BezPoint));
+
+ g_array_append_vals (result, &g_array_index (p, BezPoint, 0), p->len);
+
+ return result;
+}
+
/*!
* \brief Combine two path into a single one with the given operation
*
@@ -780,6 +797,46 @@ path_combine (const GArray *p1,
_free_splits (one_splits);
_free_splits (two_splits);
g_array_free (crossing, TRUE);
+ } else {
+ gboolean two_in_one = distance_bez_shape_point (&g_array_index (p1, BezPoint, 0), p1->len,
+ 0 /* line width */, &g_array_index (p2, BezPoint, 0).p1) == 0;
+ gboolean one_in_two = distance_bez_shape_point (&g_array_index (p2, BezPoint, 0), p2->len,
+ 0 /* line width */, &g_array_index (p1, BezPoint, 0).p1) == 0;
+
+ switch (mode) {
+ case PATH_UNION: /* Union and Exclusion just join the pathes */
+ if (two_in_one)
+ result = _path_copy (p1);
+ else if (one_in_two) /* the bigger one */
+ result = _path_copy (p2);
+ else
+ result = _make_path0 (one, NULL, two, NULL);
+ break;
+ case PATH_DIFFERENCE: /* Difference does it too, if p2 is inside p1 */
+ if (two_in_one)
+ result = _make_path0 (one, NULL, two, NULL);
+ else if (one_in_two)
+ result = NULL;
+ else
+ result = _path_copy (p1);
+ break;
+ case PATH_INTERSECTION:
+ if (two_in_one)
+ result = _path_copy (p2);
+ else if (one_in_two)
+ result = _path_copy (p1);
+ else
+ result = NULL; /* Intersection is just emtpy w/o crossing */
+ break;
+ case PATH_EXCLUSION:
+ if (two_in_one)/* with two_in_one this is like difference */
+ result = _make_path0 (one, NULL, two, NULL);
+ else if (one_in_two)
+ result = _make_path0 (two, NULL, one, NULL);
+ else /* join */
+ result = _make_path0 (one, NULL, two, NULL);
+ break;
+ }
}
g_array_free (one, TRUE);
g_array_free (two, TRUE);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]