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

gEDA-cvs: gaf.git: branch: master updated (1.5.0-20080706-341-g939998b)



The branch, master has been updated
       via  939998b8b4f6742814910a043778962f4654d5a9 (commit)
       via  d8f1aa4780edaee8b4552a7fd942126a07464b6d (commit)
       via  7648acbe63cf2b12e9afd3dbb4456cb4ee02512e (commit)
       via  0542fb0af9756b35641b6683dc3301bda9e4d792 (commit)
       via  c01757cd814e7c92cb4c64a6e134aa670b9750d1 (commit)
       via  42b77331701214e518a9249e07b0e04c6c6d501b (commit)
       via  7ad1508b5dfa3a38f30176a72b288d5eb68f5050 (commit)
       via  53193798aec9d4f833126b3e7d7811511c8b2cf3 (commit)
      from  2155126bafe11b36ca5dfaa1a9c0a06a63f136ee (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


=========
 Summary
=========

 gschem/src/o_path.c              |   80 +++++++++++++---
 libgeda/include/prototype.h      |    8 ++
 libgeda/include/prototype_priv.h |    7 ++
 libgeda/include/struct.h         |   12 +++
 libgeda/include/struct_priv.h    |    8 --
 libgeda/src/Makefile.am          |    1 +
 libgeda/src/m_hatch.c            |   29 ++++++
 libgeda/src/m_polygon.c          |  189 ++++++++++++++++++++++++++++++++++++++
 libgeda/src/o_line_basic.c       |   36 +++++---
 libgeda/src/o_path_basic.c       |   71 +++++++-------
 libgeda/src/s_path.c             |   52 +++++++++++
 11 files changed, 423 insertions(+), 70 deletions(-)
 create mode 100644 libgeda/src/m_polygon.c


=================
 Commit Messages
=================

commit 939998b8b4f6742814910a043778962f4654d5a9
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Mon Dec 8 17:15:20 2008 +0000

    Use solid painting, no XOR to draw path control lines when erasing.
    
    When the override_color is set, we are likely to be erasing the control
    lines inside o_erase_single(). To avoid leaving artifacts, don't use
    the XOR drawing context in this case.

:100644 100644 463cf5d... 540cb58... M	gschem/src/o_path.c

commit d8f1aa4780edaee8b4552a7fd942126a07464b6d
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Mon Dec 8 16:44:53 2008 +0000

    Add support for drawing curved paths with GDK

:100644 100644 00b29a9... 463cf5d... M	gschem/src/o_path.c

commit 7648acbe63cf2b12e9afd3dbb4456cb4ee02512e
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Mon Dec 8 16:44:42 2008 +0000

    Make functions in m_polygon.c public

:100644 100644 1cb9871... 0fb7a08... M	libgeda/include/prototype.h
:100644 100644 e446948... c123c2d... M	libgeda/include/prototype_priv.h

commit 0542fb0af9756b35641b6683dc3301bda9e4d792
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Mon Dec 8 16:44:36 2008 +0000

    Revert change which moved sPOINT into a private header file
    
    This structure is needed in gschem for interacting with the
    polygon routines in m_polygon.c

:100644 100644 4dacd61... efcbe4d... M	libgeda/include/struct.h
:100644 100644 1170dc3... 7358509... M	libgeda/include/struct_priv.h

commit c01757cd814e7c92cb4c64a6e134aa670b9750d1
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Mon Dec 8 16:29:11 2008 +0000

    Add rendering code to draw hatched fill in paths

:100644 100644 1a8a329... 00b29a9... M	gschem/src/o_path.c
:100644 100644 0c3ec4c... 1cb9871... M	libgeda/include/prototype.h
:100644 100644 b80685f... e446948... M	libgeda/include/prototype_priv.h

commit 42b77331701214e518a9249e07b0e04c6c6d501b
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Mon Dec 8 16:29:08 2008 +0000

    Better path printing support
    
    Allow printing of hatched paths thanks to Ed Hennessy's code to
    hatch arbitrary polygons.

:100644 100644 e446948... b80685f... M	libgeda/include/prototype_priv.h
:100644 100644 267b133... 1500e1b... M	libgeda/src/m_hatch.c
:100644 100644 9a9c5f0... 6fa1673... M	libgeda/src/o_path_basic.c

commit 7ad1508b5dfa3a38f30176a72b288d5eb68f5050
Author: Edward Hennessy <ehennes@xxxxxxxxxxxxx>
Date:   Mon Dec 8 16:29:05 2008 +0000

    Implemented distance selection mechaism for path objects
    
    This patch implements the distance calculation to path objects that may
    include both line segments and Bezier curves.  Also, the distance from
    a point to a line (o_line_shortest_distance()) is enhanced to handle the
    case where both endpoints are equal.
    
    Minor formatting edits by Peter Clifton

:100644 100644 fca8aba... 8ee6145... M	libgeda/src/m_polygon.c
:100644 100644 340aec4... 214e09b... M	libgeda/src/o_line_basic.c
:100644 100644 41c8d51... 9a9c5f0... M	libgeda/src/o_path_basic.c

commit 53193798aec9d4f833126b3e7d7811511c8b2cf3
Author: Edward Hennessy <ehennes@xxxxxxxxxxxxx>
Date:   Mon Dec 8 16:23:40 2008 +0000

    Path selection and hatching support
    
    Added utility functions for path selection and path hatching.
    
    Edited to s/POINT/sPOINT/ and other minor formatting mods by Peter Clifton

:100644 100644 3c3c64c... e446948... M	libgeda/include/prototype_priv.h
:100644 100644 9038027... 4dacd61... M	libgeda/include/struct.h
:100644 100644 d4d9bac... 78e025b... M	libgeda/src/Makefile.am
:000000 100644 0000000... fca8aba... A	libgeda/src/m_polygon.c
:100644 100644 cfe4558... ab94fef... M	libgeda/src/s_path.c

=========
 Changes
=========

commit 939998b8b4f6742814910a043778962f4654d5a9
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Mon Dec 8 17:15:20 2008 +0000

    Use solid painting, no XOR to draw path control lines when erasing.
    
    When the override_color is set, we are likely to be erasing the control
    lines inside o_erase_single(). To avoid leaving artifacts, don't use
    the XOR drawing context in this case.

diff --git a/gschem/src/o_path.c b/gschem/src/o_path.c
index 463cf5d..540cb58 100644
--- a/gschem/src/o_path.c
+++ b/gschem/src/o_path.c
@@ -828,9 +828,24 @@ static void o_path_xor_control_lines (GSCHEM_TOPLEVEL *w_current,
   int next_x, next_y;
   int last_x = 0, last_y = 0;
   PATH_SECTION *section;
+  GdkGC *gc;
+  GdkColor *color;
 
-  gdk_gc_set_foreground(w_current->outline_xor_gc,
-                        x_get_darkcolor(w_current->select_color));
+  /* If the override color is set, we're erasing, and should paint
+   * solid rather than XOR */
+
+  if (toplevel->override_color != -1 ) {
+    /* override : use the override_color instead */
+    color = x_get_color(toplevel->override_color);
+    gc = w_current->gc;
+  } else {
+    /* use the normal selection color */
+    color = x_get_darkcolor(w_current->select_color);
+    gc = w_current->outline_xor_gc;
+  }
+
+  /* set the color for the grip */
+  gdk_gc_set_foreground (gc, color);
 
   for (i = 0; i <  o_current->path->num_sections; i++) {
     section = &o_current->path->sections[i];
@@ -843,11 +858,9 @@ static void o_path_xor_control_lines (GSCHEM_TOPLEVEL *w_current,
     case PATH_CURVETO:
       /* Two control point grips */
       WORLDtoSCREEN (toplevel, section->x1, section->y1, &x, &y);
-      gdk_draw_line (w_current->backingstore, w_current->outline_xor_gc,
-                     last_x, last_y, x, y);
+      gdk_draw_line (w_current->backingstore, gc, last_x, last_y, x, y);
       WORLDtoSCREEN (toplevel, section->x2, section->y2, &x, &y);
-      gdk_draw_line (w_current->backingstore, w_current->outline_xor_gc,
-                     next_x, next_y, x, y);
+      gdk_draw_line (w_current->backingstore, gc, next_x, next_y, x, y);
       /* Fall through */
     case PATH_MOVETO:
     case PATH_MOVETO_OPEN:

commit d8f1aa4780edaee8b4552a7fd942126a07464b6d
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Mon Dec 8 16:44:53 2008 +0000

    Add support for drawing curved paths with GDK

diff --git a/gschem/src/o_path.c b/gschem/src/o_path.c
index 00b29a9..463cf5d 100644
--- a/gschem/src/o_path.c
+++ b/gschem/src/o_path.c
@@ -28,6 +28,8 @@
 #include <dmalloc.h>
 #endif
 
+#define NUM_BEZIER_SEGMENTS 100
+
 
 typedef void (*DRAW_FUNC) (GdkDrawable *w, GdkGC *gc, GdkColor *color,
                            GSCHEM_TOPLEVEL *w_current, PATH *path,
@@ -51,9 +53,12 @@ static void path_to_points_modify (GSCHEM_TOPLEVEL *w_current, PATH *path,
   int i;
   int grip_no = 0;
 
-  *points = g_new0 (GdkPoint, path->num_sections);
+  sPOINT point = { 0, 0 };
+  GArray *polygon_points;
+  BEZIER bezier;
+
+  polygon_points = g_array_new (FALSE, FALSE, sizeof (sPOINT));
 
-  *num_points = 0;
 
   for (i = 0; i <  path->num_sections; i++) {
     section = &path->sections[i];
@@ -88,21 +93,38 @@ static void path_to_points_modify (GSCHEM_TOPLEVEL *w_current, PATH *path,
 
     switch (section->code) {
       case PATH_CURVETO:
-        /* Unsupported, just fall through and draw a line */
-        /* Fall through */
+        bezier.x[0] = point.x;
+        bezier.y[0] = point.y;
+        bezier.x[1] = x1;
+        bezier.y[1] = y1;
+        bezier.x[2] = x2;
+        bezier.y[2] = y2;
+        point.x = bezier.x[3] = x3;
+        point.y = bezier.y[3] = y3;
+        m_polygon_append_bezier (polygon_points, &bezier, NUM_BEZIER_SEGMENTS);
+        break;
+
       case PATH_MOVETO_OPEN:
         /* Unsupported, just fall through and draw a line */
         /* Fall through */
+
       case PATH_MOVETO:
       case PATH_LINETO:
-        (*points)[*num_points].x = x3;
-        (*points)[*num_points].y = y3;
-        (*num_points)++;
+        point.x = x3;
+        point.y = y3;
+        m_polygon_append_point (polygon_points, point.x, point.y);
         break;
+
       case PATH_END:
         break;
     }
   }
+
+  /* WARNING:
+   * Relies on the fact that sPOINT and GdkPoint are compatible */
+
+  *num_points = polygon_points->len;
+  *points = (GdkPoint *)g_array_free (polygon_points, FALSE);
 }
 
 

commit 7648acbe63cf2b12e9afd3dbb4456cb4ee02512e
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Mon Dec 8 16:44:42 2008 +0000

    Make functions in m_polygon.c public

diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index 1cb9871..0fb7a08 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -91,6 +91,11 @@ double round_5_2_1(double unrounded);
 /* m_hatch.c */
 void m_hatch_path(PATH *path, gint angle, gint pitch, GArray *lines);
 
+/* m_polygon.c */
+void m_polygon_append_bezier(GArray *points, BEZIER *bezier, int segments);
+void m_polygon_append_point(GArray *points, int x, int y);
+
+
 /* o_arc_basic.c */
 OBJECT *o_arc_new(TOPLEVEL *toplevel, char type, int color, int x, int y, int radius, int start_angle, int end_angle);
 OBJECT *o_arc_copy(TOPLEVEL *toplevel, OBJECT *o_current);
diff --git a/libgeda/include/prototype_priv.h b/libgeda/include/prototype_priv.h
index e446948..c123c2d 100644
--- a/libgeda/include/prototype_priv.h
+++ b/libgeda/include/prototype_priv.h
@@ -61,8 +61,6 @@ void m_hatch_circle(CIRCLE *circle, gint angle, gint pitch, GArray *lines);
 void m_hatch_polygon(GArray *points, gint angle, gint pitch, GArray *lines);
 
 /* m_polygon.c */
-void m_polygon_append_bezier(GArray *points, BEZIER *bezier, int segments);
-void m_polygon_append_point(GArray *points, int x, int y);
 gboolean m_polygon_interior_point(GArray *points, int x, int y);
 double m_polygon_shortest_distance(GArray *points, int x, int y, gboolean closed);
 

commit 0542fb0af9756b35641b6683dc3301bda9e4d792
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Mon Dec 8 16:44:36 2008 +0000

    Revert change which moved sPOINT into a private header file
    
    This structure is needed in gschem for interacting with the
    polygon routines in m_polygon.c

diff --git a/libgeda/include/struct.h b/libgeda/include/struct.h
index 4dacd61..efcbe4d 100644
--- a/libgeda/include/struct.h
+++ b/libgeda/include/struct.h
@@ -36,6 +36,7 @@ typedef struct st_arc ARC;
 typedef struct st_box BOX;
 typedef struct st_picture PICTURE;
 typedef struct st_text TEXT;
+typedef struct st_point sPOINT;
 typedef struct st_transform TRANSFORM;
 typedef struct st_bezier BEZIER;
 
@@ -95,6 +96,11 @@ struct st_line {
 
 };
 
+struct st_point {
+  gint x;
+  gint y;
+};
+
 #define LINE_END1 0
 #define LINE_END2 1
 
diff --git a/libgeda/include/struct_priv.h b/libgeda/include/struct_priv.h
index 1170dc3..7358509 100644
--- a/libgeda/include/struct_priv.h
+++ b/libgeda/include/struct_priv.h
@@ -21,12 +21,4 @@
 #ifndef STRUCT_PRIV_H
 #define STRUCT_PRIV_H
 
-
-typedef struct st_point sPOINT;
-
-struct st_point {
-  gint x;
-  gint y;
-};
-
 #endif /* !STRUCT_PRIV_H */

commit c01757cd814e7c92cb4c64a6e134aa670b9750d1
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Mon Dec 8 16:29:11 2008 +0000

    Add rendering code to draw hatched fill in paths

diff --git a/gschem/src/o_path.c b/gschem/src/o_path.c
index 1a8a329..00b29a9 100644
--- a/gschem/src/o_path.c
+++ b/gschem/src/o_path.c
@@ -370,7 +370,24 @@ static void o_path_fill_hatch (GdkDrawable *w, GdkGC *gc, GdkColor *color,
                                gint angle1, gint pitch1,
                                gint angle2, gint pitch2)
 {
-  /* Not implemented */
+  int i;
+  GArray *lines;
+
+  lines = g_array_new (FALSE, FALSE, sizeof (LINE));
+
+  m_hatch_path (path, angle1, pitch1, lines);
+
+  for (i=0; i < lines->len; i++) {
+    int x1, y1, x2, y2;
+    LINE *line = &g_array_index (lines, LINE, i);
+
+    WORLDtoSCREEN (w_current->toplevel, line->x[0], line->y[0], &x1, &y1);
+    WORLDtoSCREEN (w_current->toplevel, line->x[1], line->y[1], &x2, &y2);
+    o_line_draw_solid (w, gc, color, GDK_CAP_BUTT,
+                       x1, y1, x2, y2, fill_width, -1, -1);
+  }
+
+  g_array_free (lines, TRUE);
 }
 
 
diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index 0c3ec4c..1cb9871 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -88,6 +88,9 @@ void rotate_point_90(int x, int y, int angle, int *newx, int *newy);
 void PAPERSIZEtoWORLD(int width, int height, int border, int *right, int *bottom);
 double round_5_2_1(double unrounded);
 
+/* m_hatch.c */
+void m_hatch_path(PATH *path, gint angle, gint pitch, GArray *lines);
+
 /* o_arc_basic.c */
 OBJECT *o_arc_new(TOPLEVEL *toplevel, char type, int color, int x, int y, int radius, int start_angle, int end_angle);
 OBJECT *o_arc_copy(TOPLEVEL *toplevel, OBJECT *o_current);
diff --git a/libgeda/include/prototype_priv.h b/libgeda/include/prototype_priv.h
index b80685f..e446948 100644
--- a/libgeda/include/prototype_priv.h
+++ b/libgeda/include/prototype_priv.h
@@ -58,7 +58,6 @@ void m_bounds_of_points(BOUNDS *bounds, sPOINT points[], gint count);
 /* m_hatch.c */
 void m_hatch_box(BOX *box, gint angle, gint pitch, GArray *lines);
 void m_hatch_circle(CIRCLE *circle, gint angle, gint pitch, GArray *lines);
-void m_hatch_path(PATH *path, gint angle, gint pitch, GArray *lines);
 void m_hatch_polygon(GArray *points, gint angle, gint pitch, GArray *lines);
 
 /* m_polygon.c */

commit 42b77331701214e518a9249e07b0e04c6c6d501b
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Mon Dec 8 16:29:08 2008 +0000

    Better path printing support
    
    Allow printing of hatched paths thanks to Ed Hennessy's code to
    hatch arbitrary polygons.

diff --git a/libgeda/include/prototype_priv.h b/libgeda/include/prototype_priv.h
index e446948..b80685f 100644
--- a/libgeda/include/prototype_priv.h
+++ b/libgeda/include/prototype_priv.h
@@ -58,6 +58,7 @@ void m_bounds_of_points(BOUNDS *bounds, sPOINT points[], gint count);
 /* m_hatch.c */
 void m_hatch_box(BOX *box, gint angle, gint pitch, GArray *lines);
 void m_hatch_circle(CIRCLE *circle, gint angle, gint pitch, GArray *lines);
+void m_hatch_path(PATH *path, gint angle, gint pitch, GArray *lines);
 void m_hatch_polygon(GArray *points, gint angle, gint pitch, GArray *lines);
 
 /* m_polygon.c */
diff --git a/libgeda/src/m_hatch.c b/libgeda/src/m_hatch.c
index 267b133..1500e1b 100644
--- a/libgeda/src/m_hatch.c
+++ b/libgeda/src/m_hatch.c
@@ -190,6 +190,35 @@ void m_hatch_circle(CIRCLE *circle, gint angle, gint pitch, GArray *lines)
   }
 }
 
+/*! \brief Calculates line segments to hatch a path.
+ *
+ *  This function appends new line segments to the lines GArray.  For creating
+ *  a hatch pattern, the GArray must be cleared before calling this function.
+ *  For creating cross hatch patterns, this function can be called multiple
+ *  times with a different angle or pitch while passing the same lines GArray.
+ *
+ *  \param path  [in] The path shape to hatch.
+ *  \param angle [in] The angle of the hatch lines with respect to the x axis.
+ *  \param pitch [in] The distance between hatch lines
+ *  \param lines [inout] A GArray of LINE to contain the new hatch line
+ *  segments.  This function appends new line segments to the GArray and leaves
+ *  existing GArray contents unchanged.
+ */
+void m_hatch_path (PATH *path, gint angle, gint pitch, GArray *lines)
+{
+  GArray *points;
+
+  g_return_if_fail (path != NULL);
+  g_return_if_fail (lines != NULL);
+
+  points = g_array_new (FALSE, FALSE, sizeof (sPOINT));
+
+  s_path_to_polygon (path, points);
+  m_hatch_polygon (points, angle, pitch, lines);
+
+  g_array_free (points, TRUE);
+}
+
 /*! \brief Calculates line segments to hatch an arbitrary polygon.
  *
  *  This function appends new line segments to the lines GArray.  For creating
diff --git a/libgeda/src/o_path_basic.c b/libgeda/src/o_path_basic.c
index 9a9c5f0..6fa1673 100644
--- a/libgeda/src/o_path_basic.c
+++ b/libgeda/src/o_path_basic.c
@@ -830,7 +830,27 @@ static void o_path_print_hatch (TOPLEVEL *toplevel, FILE *fp, PATH *path,
                                 int angle1, int pitch1, int angle2, int pitch2,
                                 int origin_x, int origin_y)
 {
-  /* Not implemented */
+  int i;
+  GArray *lines;
+
+  g_return_if_fail (toplevel != NULL);
+  g_return_if_fail (fp != NULL);
+
+  /* Avoid printing line widths too small */
+  if (fill_width <= 1) fill_width = 2;
+
+  lines = g_array_new (FALSE, FALSE, sizeof(LINE));
+
+  m_hatch_path (path, angle1, pitch1, lines);
+
+  for (i=0; i < lines->len; i++) {
+    LINE *line = &g_array_index (lines, LINE, i);
+
+    fprintf (fp,"%d %d %d %d %d line\n", line->x[0], line->y[0],
+                                         line->x[1], line->y[1], fill_width);
+  }
+
+  g_array_free (lines, TRUE);
 }
 
 

commit 7ad1508b5dfa3a38f30176a72b288d5eb68f5050
Author: Edward Hennessy <ehennes@xxxxxxxxxxxxx>
Date:   Mon Dec 8 16:29:05 2008 +0000

    Implemented distance selection mechaism for path objects
    
    This patch implements the distance calculation to path objects that may
    include both line segments and Bezier curves.  Also, the distance from
    a point to a line (o_line_shortest_distance()) is enhanced to handle the
    case where both endpoints are equal.
    
    Minor formatting edits by Peter Clifton

diff --git a/libgeda/src/m_polygon.c b/libgeda/src/m_polygon.c
index fca8aba..8ee6145 100644
--- a/libgeda/src/m_polygon.c
+++ b/libgeda/src/m_polygon.c
@@ -154,8 +154,36 @@ gboolean m_polygon_interior_point (GArray *points, int x, int y)
  */
 double m_polygon_shortest_distance (GArray *points, int x, int y, gboolean closed)
 {
-  /* TODO Implement */
+  gdouble shortest = G_MAXDOUBLE;
 
-  return G_MAXDOUBLE;
+  if (points->len > 0) {
+    int i = 0;
+    sPOINT point;
+
+    if (closed) {
+      point = g_array_index (points, sPOINT, points->len - 1);
+    } else {
+      point = g_array_index (points, sPOINT, i++);
+    }
+
+    while (i < points->len) {
+      double distance;
+      LINE line;
+
+      line.x[0] = point.x;
+      line.y[0] = point.y;
+
+      point = g_array_index (points, sPOINT, i++);
+
+      line.x[1] = point.x;
+      line.y[1] = point.y;
+
+      distance = o_line_shortest_distance (&line, x, y);
+
+      shortest = min (shortest, distance);
+    }
+  }
+
+  return shortest;
 }
 
diff --git a/libgeda/src/o_line_basic.c b/libgeda/src/o_line_basic.c
index 340aec4..214e09b 100644
--- a/libgeda/src/o_line_basic.c
+++ b/libgeda/src/o_line_basic.c
@@ -1218,6 +1218,9 @@ double o_line_length(OBJECT *object)
  *  end point, this function returns the distance from the given point to the
  *  closest end point.
  *
+ *  If the line represents a single point (the endpoints are the same), this
+ *  function calcualtes the distance to that point.
+ *
  *  \param [in] line  The line of an OBJECT
  *  \param [in] x The x coordinate of the given point.
  *  \param [in] y The y coordinate of the given point.
@@ -1249,23 +1252,30 @@ gdouble o_line_shortest_distance(LINE *line, gint x, gint y)
   ldx = ((double) line->x[1]) - ((double) line->x[0]);
   ldy = ((double) line->y[1]) - ((double) line->y[0]);
 
-  /* calculate parametric value of perpendicular intersection */
-  dx0 = ldx * ( x - lx0 );
-  dy0 = ldy * ( y - ly0 );
+  if (ldx == 0 && ldy == 0) {
+    /* if line is a point, just calculate distance to the point */
+    dx = x - lx0;
+    dy = y - ly0;
+
+  } else {
+    /* calculate parametric value of perpendicular intersection */
+    dx0 = ldx * (x - lx0);
+    dy0 = ldy * (y - ly0);
 
-  t = (dx0 + dy0) / ((ldx*ldx) + (ldy*ldy));
+    t = (dx0 + dy0) / (ldx * ldx + ldy * ldy);
 
-  /* constrain the parametric value to a point on the line */
-  t = max(t, 0);
-  t = min(t, 1);
+    /* constrain the parametric value to a point on the line */
+    t = max (t, 0);
+    t = min (t, 1);
 
-  /* calculate closest point on the line */
-  cx = t * ldx + lx0;
-  cy = t * ldy + ly0;
+    /* calculate closest point on the line */
+    cx = t * ldx + lx0;
+    cy = t * ldy + ly0;
 
-  /* calculate distance to closest point */
-  dx = x-cx;
-  dy = y-cy;
+    /* calculate distance to closest point */
+    dx = x - cx;
+    dy = y - cy;
+  }
 
   shortest_distance = sqrt( (dx*dx) + (dy*dy) );
 
diff --git a/libgeda/src/o_path_basic.c b/libgeda/src/o_path_basic.c
index 41c8d51..9a9c5f0 100644
--- a/libgeda/src/o_path_basic.c
+++ b/libgeda/src/o_path_basic.c
@@ -1025,8 +1025,6 @@ void o_path_print(TOPLEVEL *toplevel, FILE *fp, OBJECT *o_current,
 /*! \brief Calculates the distance between the given point and the closest
  *  point on the given path segment.
  *
- *  \todo Support for bezier path segments.
- *
  *  \param [in] object The path OBJECT
  *  \param [in] x The x coordinate of the given point.
  *  \param [in] y The y coordinate of the given point.
@@ -1035,45 +1033,28 @@ void o_path_print(TOPLEVEL *toplevel, FILE *fp, OBJECT *o_current,
  */
 gdouble o_path_shortest_distance (OBJECT *object, gint x, gint y)
 {
-  PATH_SECTION *section;
-  LINE line;
+  GArray *points;
   gdouble shortest = G_MAXDOUBLE;
-  int last_x = 0, last_y = 0;
-  int i;
+  gboolean solid;
 
-  for (i = 0; i < object->path->num_sections; i++) {
-    section = &object->path->sections[i];
-    switch (section->code) {
+  points = g_array_new (FALSE, FALSE, sizeof (sPOINT));
 
-      case PATH_CURVETO:
-        /* TODO: Shortest distance to a besier section of the path.
-         *       For now, pretend it is a straight line. */
-        /* Fall through */
-      case PATH_LINETO:
-        line.x[0] = last_x;
-        line.y[0] = last_y;
-        line.x[1] = last_x = section->x3;
-        line.y[1] = last_y = section->y3;
-        shortest = MIN (shortest, o_line_shortest_distance (&line, x, y));
-        break;
+  s_path_to_polygon (object->path, points);
 
-      case PATH_MOVETO:
-      case PATH_MOVETO_OPEN:
-        last_x = section->x3;
-        last_y = section->y3;
-        break;
+  solid = object->fill_type != FILLING_HOLLOW;    /* FIXME */
 
-      case PATH_END:
-        /* Need to consider the line back to the first point in the path */
-        line.x[0] = last_x;
-        line.y[0] = last_y;
-        line.x[1] = last_x = object->path->sections[0].x3;
-        line.y[1] = last_y = object->path->sections[0].y3;
-        shortest = MIN (shortest, o_line_shortest_distance (&line, x, y));
-        break;
-    }
+  if (!solid) {
+    shortest = m_polygon_shortest_distance (points, x, y, FALSE);
+
+  } else if (m_polygon_interior_point (points, x, y)) {
+    shortest = 0;
+
+  } else {
+    shortest = m_polygon_shortest_distance (points, x, y, TRUE);
   }
 
+  g_array_free (points, TRUE);
+
   return shortest;
 }
 

commit 53193798aec9d4f833126b3e7d7811511c8b2cf3
Author: Edward Hennessy <ehennes@xxxxxxxxxxxxx>
Date:   Mon Dec 8 16:23:40 2008 +0000

    Path selection and hatching support
    
    Added utility functions for path selection and path hatching.
    
    Edited to s/POINT/sPOINT/ and other minor formatting mods by Peter Clifton

diff --git a/libgeda/include/prototype_priv.h b/libgeda/include/prototype_priv.h
index 3c3c64c..e446948 100644
--- a/libgeda/include/prototype_priv.h
+++ b/libgeda/include/prototype_priv.h
@@ -60,6 +60,12 @@ void m_hatch_box(BOX *box, gint angle, gint pitch, GArray *lines);
 void m_hatch_circle(CIRCLE *circle, gint angle, gint pitch, GArray *lines);
 void m_hatch_polygon(GArray *points, gint angle, gint pitch, GArray *lines);
 
+/* m_polygon.c */
+void m_polygon_append_bezier(GArray *points, BEZIER *bezier, int segments);
+void m_polygon_append_point(GArray *points, int x, int y);
+gboolean m_polygon_interior_point(GArray *points, int x, int y);
+double m_polygon_shortest_distance(GArray *points, int x, int y, gboolean closed);
+
 /* m_transform.c */
 void m_transform_combine(TRANSFORM *result, TRANSFORM *a, TRANSFORM *b );
 void m_transform_init(TRANSFORM *transform);
@@ -217,6 +223,9 @@ char *s_color_ps_string(int color);
 gchar* s_encoding_base64_encode (gchar* src, guint srclen, guint* dstlenp, gboolean strict);
 gchar* s_encoding_base64_decode (gchar* src, guint srclen, guint* dstlenp);
 
+/* s_path.c */
+void s_path_to_polygon(PATH *path, GArray *points);
+
 /* s_textbuffer.c */
 TextBuffer *s_textbuffer_new (gchar *data, const gint size);
 TextBuffer *s_textbuffer_free (TextBuffer *tb);
diff --git a/libgeda/include/struct.h b/libgeda/include/struct.h
index 9038027..4dacd61 100644
--- a/libgeda/include/struct.h
+++ b/libgeda/include/struct.h
@@ -37,6 +37,7 @@ typedef struct st_box BOX;
 typedef struct st_picture PICTURE;
 typedef struct st_text TEXT;
 typedef struct st_transform TRANSFORM;
+typedef struct st_bezier BEZIER;
 
 typedef struct st_object OBJECT;
 typedef struct st_page PAGE;
@@ -136,6 +137,11 @@ struct st_arc {
 #define ARC_START_ANGLE 2
 #define ARC_END_ANGLE 3
 
+struct st_bezier {
+  int x[4];
+  int y[4];
+};
+
 struct st_box {
   /* upper is considered the origin */
   int upper_x, upper_y; /* world */	
diff --git a/libgeda/src/Makefile.am b/libgeda/src/Makefile.am
index d4d9bac..78e025b 100644
--- a/libgeda/src/Makefile.am
+++ b/libgeda/src/Makefile.am
@@ -27,6 +27,7 @@ libgeda_la_SOURCES = \
 	m_basic.c \
 	m_bounds.c \
 	m_hatch.c \
+	m_polygon.c \
 	m_transform.c \
 	o_arc_basic.c \
 	o_attrib.c \
diff --git a/libgeda/src/m_polygon.c b/libgeda/src/m_polygon.c
new file mode 100644
index 0000000..fca8aba
--- /dev/null
+++ b/libgeda/src/m_polygon.c
@@ -0,0 +1,161 @@
+/* gEDA - GPL Electronic Design Automation
+ * libgeda - gEDA's library
+ * Copyright (C) 1998-2008 Ales Hvezda
+ * Copyright (C) 1998-2008 gEDA Contributors (see ChangeLog for details)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
+ */
+#include <config.h>
+#include <math.h>
+#include <string.h>
+#include <libgeda_priv.h>
+
+/*! \brief Appends a bezier curve to the polygon
+ *
+ *  \param points [inout] The vertices of the polygon. This parameter must not
+ *  be NULL.
+ *  \param bezier [in] The bezier curve to append.
+ *  \param segments [in] The number of segments to subdivide the bezier curve into.
+ */
+void m_polygon_append_bezier (GArray *points, BEZIER *bezier, int segments)
+{
+  m_polygon_append_point (points, bezier->x[0], bezier->y[0]);
+
+  if (segments > 1) {
+    int i;
+
+    double a = 3 / (double) segments;
+    double b = 6 / pow (segments, 2);
+    double c = 6 / pow (segments, 3);
+
+    double x = bezier->x[0];
+    double xd = a * (bezier->x[1] - bezier->x[0]);
+    double xdd = b * (bezier->x[0] - 2 * bezier->x[1] + bezier->x[2]);
+    double xddd = c * (3 * (bezier->x[1] - bezier->x[2]) + bezier->x[3] - bezier->x[0]);
+
+    double xdd_div2 = xdd / 2;
+    double xddd_div2 = xddd / 2;
+    double xddd_div6 = xddd / 6;
+
+    double y = bezier->y[0];
+    double yd = a * (bezier->y[1] - bezier->y[0]);
+    double ydd = b * (bezier->y[0] - 2 * bezier->y[1] + bezier->y[2]);
+    double yddd = c * (3 * (bezier->y[1] - bezier->y[2]) + bezier->y[3] - bezier->y[0]);
+
+    double ydd_div2 = ydd / 2;
+    double yddd_div2 = yddd / 2;
+    double yddd_div6 = yddd / 6;
+
+    for (i=1; i < segments; i++) {
+      x += xd + xdd_div2 + xddd_div6;
+      xd += xdd + xddd_div2;
+      xdd += xddd;
+      xdd_div2 += xddd_div2;
+
+      y += yd + ydd_div2 + yddd_div6;
+      yd += ydd + yddd_div2;
+      ydd += yddd;
+      ydd_div2 += yddd_div2;
+
+      m_polygon_append_point (points, round (x), round (y));
+    }
+  }
+
+  m_polygon_append_point (points, bezier->x[3], bezier->y[3]);
+}
+
+/*! \brief Appends a point to the list of vertices in a polygon
+ *
+ *  \param points [inout] The vertices of the polygon. This parameter must not
+ *  be NULL.
+ *  \param x [in] The x coordinate of the point to append.
+ *  \param y [in] The y coordinate of the point to append.
+ */
+void m_polygon_append_point (GArray *points, int x, int y)
+{
+  sPOINT point = { x, y };
+
+  point.x = x;
+  point.y = y;
+
+  if (points->len == 0 ||
+      memcmp (&g_array_index (points, sPOINT, points->len - 1),
+              &point, sizeof (sPOINT)) != 0) {
+    g_array_append_val (points, point);
+  }
+}
+
+/*! \brief Determines if a point lies inside a polygon
+ *
+ *  TODO Untested
+ *
+ *  \param points [in] The vertices of the polygon.  This function assumes the
+ *  list of points represents a closed polygon.  If the first and last point do
+ *  not match, the line segment between them is implied.  This parameter must
+ *  not be NULL.
+ *  \param x [in] The x coordinate of the given point.
+ *  \param y [in] The y coordinate of the given point.
+ *  \returns TRUE if the point lies inside the polygon, FALSE if the point lies
+ *  outside the polygon.
+ */
+gboolean m_polygon_interior_point (GArray *points, int x, int y)
+{
+  int count = 0;
+
+  if (points->len > 0) {
+    int i;
+    sPOINT p1 = g_array_index (points, sPOINT, points->len - 1);
+
+    for (i=0; i < points->len; i++) {
+      sPOINT p0 = p1;
+      double xi;
+
+      p1 = g_array_index (points, sPOINT, i);
+
+      if (y < p0.y && y < p1.y)
+        continue;
+
+      if (y >= p0.y && y >= p1.y)
+        continue;
+
+      xi = ((double) (p1.x - p0.x)) * (y - p0.y) / (p1.y - p0.y) + p0.x;
+
+      if (x < xi)
+        count++;
+    }
+  }
+  return (count % 2) == 1;  /* odd */
+}
+
+/*! \brief Calculates the distance between the given point and the closest
+ *  point on the perimeter of the polygon.
+ *
+ *  \param [in] points The polygon, where polygon != NULL.
+ *  \param [in] x      The x coordinate of the given point.
+ *  \param [in] y      The y coordinate of the given point.
+ *  \param [in] closed If TRUE, the function treats the polygon as a closed
+ *  shape, creating a line between the first and last points, if needed.  If
+ *  the first and last points are equal, or inherintly closed, this parameter
+ *  does not matter.
+ *  \return The shortest distance from the polygon to the point.  With an
+ *  invalid parameter, this function returns G_MAXDOUBLE.
+ */
+double m_polygon_shortest_distance (GArray *points, int x, int y, gboolean closed)
+{
+  /* TODO Implement */
+
+  return G_MAXDOUBLE;
+}
+
diff --git a/libgeda/src/s_path.c b/libgeda/src/s_path.c
index cfe4558..ab94fef 100644
--- a/libgeda/src/s_path.c
+++ b/libgeda/src/s_path.c
@@ -43,6 +43,8 @@
 
 #include "libgeda_priv.h"
 
+#define NUM_BEZIER_SEGMENTS 100
+
 
 PATH *s_path_new (void)
 {
@@ -696,3 +698,53 @@ char *s_path_string_from_path (const PATH *path)
 
   return g_string_free (path_string, FALSE);
 }
+
+/*! \brief Converts a path to a polygon
+ *
+ *  \param path [in] The path to convert to a polygon.  This parameter must not
+ *  be NULL.
+ *  \param points [out] An array of the polygon's vertices.  This parameter
+ *  must not be NULL.
+ */
+void s_path_to_polygon (PATH *path, GArray *points)
+{
+  int i;
+  sPOINT point = { 0, 0 };
+
+  if (points->len > 0) {
+    g_array_remove_range (points, 0, points->len - 1);
+  }
+
+  for (i = 0; i < path->num_sections; i++) {
+    BEZIER bezier;
+    PATH_SECTION *section = &path->sections[i];
+
+    switch (section->code) {
+      case PATH_CURVETO:
+        bezier.x[0] = point.x;
+        bezier.y[0] = point.y;
+        bezier.x[1] = section->x1;
+        bezier.y[1] = section->y1;
+        bezier.x[2] = section->x2;
+        bezier.y[2] = section->y2;
+        point.x = bezier.x[3] = section->x3;
+        point.y = bezier.y[3] = section->y3;
+        m_polygon_append_bezier (points, &bezier, NUM_BEZIER_SEGMENTS);
+        break;
+
+      case PATH_MOVETO_OPEN:
+        /* Unsupported, just fall through and draw a line */
+        /* Fall through */
+
+      case PATH_MOVETO:
+      case PATH_LINETO:
+        point.x = section->x3;
+        point.y = section->y3;
+        m_polygon_append_point (points, point.x, point.y);
+        break;
+
+      case PATH_END:
+        break;
+    }
+  }
+}




_______________________________________________
geda-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs