[dia] Bezier* : fix some more ignorance regarding BEZ_LINE_TO



commit 62dab7da687c4898cef9114a2017955c41a177a0
Author: Hans Breuer <hans breuer org>
Date:   Wed Oct 3 21:34:14 2012 +0200

    Bezier* : fix some more ignorance regarding BEZ_LINE_TO

 lib/bezier-common.c          |   42 +++++++++++++++++++++++++++-
 lib/bezier-common.h          |    2 +
 lib/bezier_conn.c            |   33 ----------------------
 lib/bezier_conn.h            |    2 -
 lib/beziershape.c            |   61 +++++++++++++----------------------------
 lib/beziershape.h            |    2 -
 lib/geometry.c               |   10 ++++---
 lib/geometry.h               |    3 +-
 objects/standard/bezier.c    |    9 +++---
 objects/standard/beziergon.c |    4 +-
 10 files changed, 76 insertions(+), 92 deletions(-)
---
diff --git a/lib/bezier-common.c b/lib/bezier-common.c
index 52260c1..063bc6e 100644
--- a/lib/bezier-common.c
+++ b/lib/bezier-common.c
@@ -108,6 +108,40 @@ beziercommon_copy (BezierCommon *from, BezierCommon *to)
 }
 
 /*!
+ * \brief Return the segment of the bezier closest to a given point.
+ * @param bezier The bezier object
+ * @param point A point to find the closest segment to.
+ * @param line_width Line width of the bezier line.
+ * @return The index of the segment closest to point.
+ * \memberof BezierCommon
+ */
+int
+beziercommon_closest_segment (BezierCommon *bezier,
+			      const Point  *point,
+			      real          line_width)
+{
+  Point last;
+  int i;
+  real dist = G_MAXDOUBLE;
+  int closest;
+
+  closest = 0;
+  last = bezier->points[0].p1;
+  for (i = 0; i < bezier->num_points - 1; i++) {
+    real new_dist = distance_bez_seg_point(&last, &bezier->points[i+1], line_width, point);
+    if (new_dist < dist) {
+      dist = new_dist;
+      closest = i;
+    }
+    if (bezier->points[i+1].type == BEZ_CURVE_TO)
+      last = bezier->points[i+1].p3;
+    else
+      last = bezier->points[i+1].p1;
+  }
+  return closest;
+}
+
+/*!
  * \brief Draw control lines of the given _BezPoint array
  */
 void
@@ -129,7 +163,11 @@ bezier_draw_control_lines (int          num_points,
   startpoint = points[0].p1;
   for (i = 1; i < num_points; i++) {
     DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &startpoint, &points[i].p1, &line_colour);
-    DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &points[i].p2, &points[i].p3, &line_colour);
-    startpoint = points[i].p3;
+    if (points[i].type == BEZ_CURVE_TO) {
+      DIA_RENDERER_GET_CLASS(renderer)->draw_line(renderer, &points[i].p2, &points[i].p3, &line_colour);
+      startpoint = points[i].p3;
+    } else {
+      startpoint = points[i].p1;
+    }
   }
 }
diff --git a/lib/bezier-common.h b/lib/bezier-common.h
index 7f115da..428de71 100644
--- a/lib/bezier-common.h
+++ b/lib/bezier-common.h
@@ -25,6 +25,7 @@
 #define BEZIER_COMMON_H
 
 #include "diatypes.h"
+#include "geometry.h" /* for real */
 
 typedef enum {
   BEZ_CORNER_SYMMETRIC,
@@ -46,6 +47,7 @@ struct _BezierCommon {
 
 void beziercommon_set_points (BezierCommon *bezier, int num, const BezPoint *pts);
 void beziercommon_copy (BezierCommon *from, BezierCommon *to);
+int  beziercommon_closest_segment (BezierCommon *bezier, const Point *point, real line_width);
 
 void bezier_draw_control_lines (int num_points, BezPoint *pts, DiaRenderer *renderer);
 
diff --git a/lib/bezier_conn.c b/lib/bezier_conn.c
index 3b4b6ed..190bb17 100644
--- a/lib/bezier_conn.c
+++ b/lib/bezier_conn.c
@@ -267,39 +267,6 @@ bezierconn_move (BezierConn *bezier, Point *to)
 }
 
 /*!
- * \brief Return the segment of the bezier closest to a given point.
- * @param bezier The bezier object
- * @param point A point to find the closest segment to.
- * @param line_width Line width of the bezier line.
- * @return The index of the segment closest to point.
- * \memberof BezierConn
- */
-int
-bezierconn_closest_segment (BezierConn *bezier,
-			    Point *point,
-			    real line_width)
-{
-  Point last;
-  int i;
-  real dist = G_MAXDOUBLE;
-  int closest;
-
-  closest = 0;
-  last = bezier->bezier.points[0].p1;
-  for (i = 0; i < bezier->bezier.num_points - 1; i++) {
-    real new_dist = distance_bez_seg_point(&last, &bezier->bezier.points[i+1].p1,
-				&bezier->bezier.points[i+1].p2, &bezier->bezier.points[i+1].p3,
-				line_width, point);
-    if (new_dist < dist) {
-      dist = new_dist;
-      closest = i;
-    }
-    last = bezier->bezier.points[i+1].p3;
-  }
-  return closest;
-}
-
-/*!
  * \brief Return the handle closest to a given point.
  * @param bezier A bezier object
  * @param point A point to find distances from
diff --git a/lib/bezier_conn.h b/lib/bezier_conn.h
index ed14fef..b11c9d1 100644
--- a/lib/bezier_conn.h
+++ b/lib/bezier_conn.h
@@ -66,8 +66,6 @@ real bezierconn_distance_from(BezierConn *bez, Point *point,
 			      real line_width);
 Handle *bezierconn_closest_handle(BezierConn *bez, Point *point);
 Handle *bezierconn_closest_major_handle(BezierConn *bez, Point *point);
-int bezierconn_closest_segment(BezierConn *bez, Point *point,
-			       real line_width);
 
 #define BEZCONN_COMMON_PROPERTIES \
   OBJECT_COMMON_PROPERTIES, \
diff --git a/lib/beziershape.c b/lib/beziershape.c
index 89c3d11..1c0cbde 100644
--- a/lib/beziershape.c
+++ b/lib/beziershape.c
@@ -278,40 +278,6 @@ beziershape_move (BezierShape *bezier, Point *to)
 }
 
 /*!
- * \brief Return the segment of the bezier closest to a given point.
- * @param bezier The bezier object
- * @param point A point to find the closest segment to.
- * @param line_width Line width of the bezier line.
- * @return The index of the segment closest to point.
- * \memberof BezierShape
- */
-int
-beziershape_closest_segment (BezierShape *bezier,
-			     Point *point,
-			     real line_width)
-{
-  Point last;
-  int i;
-  real dist = G_MAXDOUBLE;
-  int closest;
-
-  closest = 0;
-  last = bezier->bezier.points[0].p1;
-  /* the first point is just move-to so there is no need to consider p2,p3 of it */
-  for (i = 1; i < bezier->bezier.num_points; i++) {
-    real new_dist = distance_bez_seg_point(&last, &bezier->bezier.points[i].p1,
-			&bezier->bezier.points[i].p2, &bezier->bezier.points[i].p3,
-			line_width, point);
-    if (new_dist < dist) {
-      dist = new_dist;
-      closest = i;
-    }
-    last = bezier->bezier.points[i].p3;
-  }
-  return closest;
-}
-
-/*!
  * \brief Return the handle closest to a given point.
  * @param bezier A bezier object
  * @param point A point to find distances from
@@ -484,6 +450,11 @@ beziershape_add_segment (BezierShape *bezier,
   Point startpoint;
   Point other;
 
+  g_return_val_if_fail (segment >= 0 && segment < bezier->bezier.num_points, NULL);
+
+  if (segment == 0) /* don't want to add this, just take the next one */
+    ++segment;
+
   if (segment != 1)
     startpoint = bezier->bezier.points[segment-1].p3;
   else 
@@ -763,15 +734,23 @@ beziershape_update_data (BezierShape *bezier)
     obj->connections[2*i-2]->pos = last;
     obj->connections[2*i-2]->directions =
       find_slope_directions(last, bezier->bezier.points[i].p1);
-    obj->connections[2*i-1]->pos.x =
-      (last.x + 3*bezier->bezier.points[i].p1.x + 3*bezier->bezier.points[i].p2.x +
-       bezier->bezier.points[i].p3.x)/8;
-    obj->connections[2*i-1]->pos.y =
-      (last.y + 3*bezier->bezier.points[i].p1.y + 3*bezier->bezier.points[i].p2.y +
-       bezier->bezier.points[i].p3.y)/8;
+    if (bezier->bezier.points[i].type == BEZ_CURVE_TO) {
+      obj->connections[2*i-1]->pos.x =
+        (last.x + 3*bezier->bezier.points[i].p1.x + 3*bezier->bezier.points[i].p2.x +
+         bezier->bezier.points[i].p3.x)/8;
+      obj->connections[2*i-1]->pos.y =
+        (last.y + 3*bezier->bezier.points[i].p1.y + 3*bezier->bezier.points[i].p2.y +
+         bezier->bezier.points[i].p3.y)/8;
+    } else {
+      obj->connections[2*i-1]->pos.x = (last.x + bezier->bezier.points[i].p1.x) / 2;
+      obj->connections[2*i-1]->pos.y = (last.y + bezier->bezier.points[i].p1.y) / 2;
+    }
     obj->connections[2*i-1]->directions = 
       find_slope_directions(slopepoint1, slopepoint2);
-    last = bezier->bezier.points[i].p3;
+    if (bezier->bezier.points[i].type == BEZ_CURVE_TO)
+      last = bezier->bezier.points[i].p3;
+    else
+      last = bezier->bezier.points[i].p1;
   }
   
   /* Find the middle of the object (or some approximation at least) */
diff --git a/lib/beziershape.h b/lib/beziershape.h
index e7ba98b..d5c1bb0 100644
--- a/lib/beziershape.h
+++ b/lib/beziershape.h
@@ -70,8 +70,6 @@ real beziershape_distance_from(BezierShape *bezier, Point *point,
 			       real line_width);
 Handle *beziershape_closest_handle(BezierShape *bezier, Point *point);
 Handle *beziershape_closest_major_handle(BezierShape *bezier, Point *point);
-int beziershape_closest_segment(BezierShape *bezier, Point *point,
-				real line_width);
 
 #define BEZSHAPE_COMMON_PROPERTIES \
   OBJECT_COMMON_PROPERTIES, \
diff --git a/lib/geometry.c b/lib/geometry.c
index 12e7bb5..eb0cf3f 100644
--- a/lib/geometry.c
+++ b/lib/geometry.c
@@ -290,12 +290,14 @@ bez_point_distance_and_ray_crosses(const Point *b1,
 }
 
 real
-distance_bez_seg_point(const Point *b1, const Point *b2, 
-                       const Point *b3, const Point *b4,
+distance_bez_seg_point(const Point *b1, const BezPoint *b2, 
 		       real line_width, const Point *point)
 {
-  return bez_point_distance_and_ray_crosses(b1, b2, b3, b4,
-					    line_width, point, NULL);
+  if (b2->type == BEZ_CURVE_TO)
+    return bez_point_distance_and_ray_crosses(b1, &b2->p1, &b2->p2, &b2->p3,
+					      line_width, point, NULL);
+  else
+    return distance_line_point(b1, &b2->p1, line_width, point);
 }
 			     
 real
diff --git a/lib/geometry.h b/lib/geometry.h
index 6b48c47..b8cb893 100644
--- a/lib/geometry.h
+++ b/lib/geometry.h
@@ -355,8 +355,7 @@ real distance_polygon_point(const Point *poly, guint npoints,
 			    real line_width, const Point *point);
 
 /* bezier distance calculations */
-real distance_bez_seg_point(const Point *b1, const Point *b2, 
-                            const Point *b3, const Point *b4,
+real distance_bez_seg_point(const Point *b1, const BezPoint *b2,
 			    real line_width, const Point *point);
 real distance_bez_line_point(const BezPoint *b, guint npoints,
 			     real line_width, const Point *point);
diff --git a/objects/standard/bezier.c b/objects/standard/bezier.c
index a40c610..63ac1d0 100644
--- a/objects/standard/bezier.c
+++ b/objects/standard/bezier.c
@@ -210,9 +210,11 @@ bezierline_distance_from(Bezierline *bezierline, Point *point)
   }
 }
 
-static int bezierline_closest_segment(Bezierline *bezierline, Point *point) {
+static int 
+bezierline_closest_segment(Bezierline *bezierline, Point *point)
+{
   BezierConn *bez = &bezierline->bez;
-  return bezierconn_closest_segment(bez, point, bezierline->line_width);
+  return beziercommon_closest_segment(&bez->bezier, point, bezierline->line_width);
 }
 
 static void
@@ -732,8 +734,7 @@ bezierline_delete_segment_callback (DiaObject *obj, Point *clicked, gpointer dat
   Bezierline *bezierline = (Bezierline*) obj;
   ObjectChange *change;
   
-  seg_nr = bezierconn_closest_segment(&bezierline->bez, clicked,
-				      bezierline->line_width);
+  seg_nr = beziercommon_closest_segment(&bezierline->bez.bezier, clicked, bezierline->line_width);
 
   change = bezierconn_remove_segment(&bezierline->bez, seg_nr+1);
   bezierline_update_data(bezierline);
diff --git a/objects/standard/beziergon.c b/objects/standard/beziergon.c
index de39b1e..db43886 100644
--- a/objects/standard/beziergon.c
+++ b/objects/standard/beziergon.c
@@ -171,8 +171,8 @@ beziergon_distance_from(Beziergon *beziergon, Point *point)
 static int
 beziergon_closest_segment(Beziergon *beziergon, Point *point)
 {
-  return beziershape_closest_segment(&beziergon->bezier, point,
-				     beziergon->line_width);
+  return beziercommon_closest_segment(&beziergon->bezier.bezier, point,
+				      beziergon->line_width);
 }
 
 static void



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]