• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

作図ソフト dia の改良版


Commit MetaInfo

修訂7546391a16212dfadc514f353712e04618df4928 (tree)
時間2014-09-14 21:12:29
作者Hans Breuer <hans@breu...>
CommiterHans Breuer

Log Message

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.

Change Summary

差異

--- a/app/disp_callbacks.c
+++ b/app/disp_callbacks.c
@@ -238,15 +238,18 @@ _combine_to_path_callback (GtkAction *action, gpointer data)
238238 (change->apply)(change, dia);
239239 /* add the new object with undo */
240240 undo_insert_objects(dia, g_list_prepend(NULL, obj), 1);
241- undo_set_transactionpoint(ddisp->diagram->undo);
242-
243241 diagram_add_object (dia, obj);
244242 diagram_select(dia, obj);
243+ undo_set_transactionpoint(ddisp->diagram->undo);
245244 object_add_updates(obj, dia);
246-
247- ddisplay_do_update_menu_sensitivity(ddisp);
248- diagram_flush(dia);
245+ } else {
246+ /* path combination result is empty, this is just a delete */
247+ Change *change = undo_delete_objects_children(ddisp->diagram, cut_list);
248+ (change->apply)(change, ddisp->diagram);
249+ undo_set_transactionpoint(ddisp->diagram->undo);
249250 }
251+ ddisplay_do_update_menu_sensitivity(ddisp);
252+ diagram_flush(dia);
250253 g_list_free (cut_list);
251254 }
252255 static void
--- a/lib/diapathrenderer.c
+++ b/lib/diapathrenderer.c
@@ -874,12 +874,11 @@ create_standard_path_from_list (GList *objects,
874874 }
875875 if (p1 && p2) {
876876 GArray *combined = path_combine (p1, p2, mode);
877- if (combined) {
878- g_array_free (p1, TRUE);
879- p1 = combined;
880- g_array_free (p2, TRUE);
881- p2 = NULL;
882- }
877+ /* combined == NULL is just passed on */
878+ g_array_free (p1, TRUE);
879+ p1 = combined;
880+ g_array_free (p2, TRUE);
881+ p2 = NULL;
883882 } else {
884883 p1 = p2;
885884 p2 = NULL;
--- a/lib/path-math.c
+++ b/lib/path-math.c
@@ -302,6 +302,13 @@ struct _Split {
302302 GArray *path; /*!< subpath copy */
303303 };
304304
305+/*!
306+ * \brief Extract splits from crossing
307+ *
308+ * Crossing is the array of Intersection which contains split information
309+ * from crossing between two paths. This function separates the
310+ * information into splits specific to a single path.
311+ */
305312 static GArray *
306313 _extract_splits (const GArray *crossing, gboolean one)
307314 {
@@ -619,8 +626,8 @@ _make_path0 (GArray *one, /*!< array<BezierSegment> from first path */
619626 for (i = 0; i < segs->len; ++i) {
620627 BezierSegment *seg = &g_array_index (segs, BezierSegment, i);
621628 /* every split starts with a move-to */
622- if ( isp < splits->len
623- && 0
629+ if ( splits
630+ && isp < splits->len
624631 && i == g_array_index (splits, Split, isp).seg
625632 && g_array_index (result, BezPoint, result->len - 1).type != BEZ_MOVE_TO) {
626633 bp.type = BEZ_MOVE_TO;
@@ -727,6 +734,16 @@ _make_path (GArray *one, /*!< array<BezierSegment> from first path */
727734 return result;
728735 }
729736
737+static GArray *
738+_path_copy (const GArray *p)
739+{
740+ GArray *result = g_array_new (FALSE, FALSE, sizeof(BezPoint));
741+
742+ g_array_append_vals (result, &g_array_index (p, BezPoint, 0), p->len);
743+
744+ return result;
745+}
746+
730747 /*!
731748 * \brief Combine two path into a single one with the given operation
732749 *
@@ -780,6 +797,46 @@ path_combine (const GArray *p1,
780797 _free_splits (one_splits);
781798 _free_splits (two_splits);
782799 g_array_free (crossing, TRUE);
800+ } else {
801+ gboolean two_in_one = distance_bez_shape_point (&g_array_index (p1, BezPoint, 0), p1->len,
802+ 0 /* line width */, &g_array_index (p2, BezPoint, 0).p1) == 0;
803+ gboolean one_in_two = distance_bez_shape_point (&g_array_index (p2, BezPoint, 0), p2->len,
804+ 0 /* line width */, &g_array_index (p1, BezPoint, 0).p1) == 0;
805+
806+ switch (mode) {
807+ case PATH_UNION: /* Union and Exclusion just join the pathes */
808+ if (two_in_one)
809+ result = _path_copy (p1);
810+ else if (one_in_two) /* the bigger one */
811+ result = _path_copy (p2);
812+ else
813+ result = _make_path0 (one, NULL, two, NULL);
814+ break;
815+ case PATH_DIFFERENCE: /* Difference does it too, if p2 is inside p1 */
816+ if (two_in_one)
817+ result = _make_path0 (one, NULL, two, NULL);
818+ else if (one_in_two)
819+ result = NULL;
820+ else
821+ result = _path_copy (p1);
822+ break;
823+ case PATH_INTERSECTION:
824+ if (two_in_one)
825+ result = _path_copy (p2);
826+ else if (one_in_two)
827+ result = _path_copy (p1);
828+ else
829+ result = NULL; /* Intersection is just emtpy w/o crossing */
830+ break;
831+ case PATH_EXCLUSION:
832+ if (two_in_one)/* with two_in_one this is like difference */
833+ result = _make_path0 (one, NULL, two, NULL);
834+ else if (one_in_two)
835+ result = _make_path0 (two, NULL, one, NULL);
836+ else /* join */
837+ result = _make_path0 (one, NULL, two, NULL);
838+ break;
839+ }
783840 }
784841 g_array_free (one, TRUE);
785842 g_array_free (two, TRUE);