mirror of https://github.com/GNOME/gimp.git
app/vectors/gimpstroke.[ch] Applied a modified patch from Geert Jordaens
2004-06-30 Simon Budig <simon@gimp.org> * app/vectors/gimpstroke.[ch] * tools/pdbgen/pdb/paths.pdb: Applied a modified patch from Geert Jordaens that implements the gimp-path-get-point-at-dist PDB function (fixes bug #138754). * app/pdb/paths_cmds.c: regenerated
This commit is contained in:
parent
3cec641627
commit
2cf661fc16
|
@ -1,3 +1,12 @@
|
|||
2004-06-30 Simon Budig <simon@gimp.org>
|
||||
|
||||
* app/vectors/gimpstroke.[ch]
|
||||
* tools/pdbgen/pdb/paths.pdb: Applied a modified patch from
|
||||
Geert Jordaens that implements the gimp-path-get-point-at-dist
|
||||
PDB function (fixes bug #138754).
|
||||
|
||||
* app/pdb/paths_cmds.c: regenerated
|
||||
|
||||
2004-06-30 Michael Natterer <mitch@gimp.org>
|
||||
|
||||
* app/widgets/gimptoolbox.c (gimp_toolbox_button_accel_changed):
|
||||
|
|
|
@ -655,6 +655,11 @@ path_get_point_at_dist_invoker (Gimp *gimp,
|
|||
gint32 y_point = 0;
|
||||
gdouble gradient = 0;
|
||||
GimpVectors *vectors;
|
||||
GimpStroke *stroke;
|
||||
gdouble distance_along;
|
||||
gdouble stroke_length;
|
||||
gdouble stroke_distance;
|
||||
GimpCoords position;
|
||||
|
||||
gimage = gimp_image_get_by_ID (gimp, args[0].value.pdb_int);
|
||||
if (! GIMP_IS_IMAGE (gimage))
|
||||
|
@ -668,11 +673,44 @@ path_get_point_at_dist_invoker (Gimp *gimp,
|
|||
|
||||
if (vectors)
|
||||
{
|
||||
g_warning ("FIXME: path_get_point_at_dist() is unimplemented");
|
||||
success = FALSE;
|
||||
distance_along = 0.0;
|
||||
stroke = gimp_vectors_stroke_get_next (vectors, NULL);
|
||||
|
||||
while (stroke != NULL )
|
||||
{
|
||||
stroke_length = gimp_stroke_get_length (stroke, 0.5);
|
||||
|
||||
if (distance_along + stroke_length < distance)
|
||||
{
|
||||
distance_along += stroke_length;
|
||||
}
|
||||
else
|
||||
{
|
||||
stroke_distance = distance - distance_along;
|
||||
stroke_distance = stroke_distance < 0 ? 0: stroke_distance;
|
||||
|
||||
if (!gimp_stroke_get_point_at_dist (stroke, stroke_distance, 0.5,
|
||||
&position, &gradient))
|
||||
{
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
success = TRUE;
|
||||
x_point = ROUND (position.x);
|
||||
y_point = ROUND (position.y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
stroke = gimp_vectors_stroke_get_next (vectors, stroke);
|
||||
}
|
||||
}
|
||||
else
|
||||
success = FALSE;
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return_args = procedural_db_return_args (&path_get_point_at_dist_proc, success);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "vectors-types.h"
|
||||
|
||||
#include "core/gimp-utils.h"
|
||||
#include "core/gimpcoords.h"
|
||||
|
||||
#include "gimpanchor.h"
|
||||
#include "gimpstroke.h"
|
||||
|
@ -126,7 +127,8 @@ gboolean gimp_stroke_real_connect_stroke (GimpStroke *stroke,
|
|||
|
||||
static gboolean gimp_stroke_real_is_empty (const GimpStroke *stroke);
|
||||
|
||||
static gdouble gimp_stroke_real_get_length (const GimpStroke *stroke);
|
||||
static gdouble gimp_stroke_real_get_length (const GimpStroke *stroke,
|
||||
const gdouble precision);
|
||||
static gdouble gimp_stroke_real_get_distance (const GimpStroke *stroke,
|
||||
const GimpCoords *coord);
|
||||
static GArray * gimp_stroke_real_interpolate (const GimpStroke *stroke,
|
||||
|
@ -149,6 +151,11 @@ static GList * gimp_stroke_real_get_draw_controls (const GimpStroke *stroke);
|
|||
static GArray * gimp_stroke_real_get_draw_lines (const GimpStroke *stroke);
|
||||
static GArray * gimp_stroke_real_control_points_get (const GimpStroke *stroke,
|
||||
gboolean *ret_closed);
|
||||
static gboolean gimp_stroke_real_get_point_at_dist (const GimpStroke *stroke,
|
||||
const gdouble dist,
|
||||
const gdouble precision,
|
||||
GimpCoords *position,
|
||||
gdouble *gradient);
|
||||
|
||||
/* private variables */
|
||||
|
||||
|
@ -230,6 +237,7 @@ gimp_stroke_class_init (GimpStrokeClass *klass)
|
|||
klass->is_empty = gimp_stroke_real_is_empty;
|
||||
klass->get_length = gimp_stroke_real_get_length;
|
||||
klass->get_distance = gimp_stroke_real_get_distance;
|
||||
klass->get_point_at_dist = gimp_stroke_real_get_point_at_dist;
|
||||
klass->interpolate = gimp_stroke_real_interpolate;
|
||||
|
||||
klass->duplicate = gimp_stroke_real_duplicate;
|
||||
|
@ -849,19 +857,45 @@ gimp_stroke_real_is_empty (const GimpStroke *stroke)
|
|||
|
||||
|
||||
gdouble
|
||||
gimp_stroke_get_length (const GimpStroke *stroke)
|
||||
gimp_stroke_get_length (const GimpStroke *stroke,
|
||||
const gdouble precision)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_STROKE (stroke), 0.0);
|
||||
|
||||
return GIMP_STROKE_GET_CLASS (stroke)->get_length (stroke);
|
||||
return GIMP_STROKE_GET_CLASS (stroke)->get_length (stroke, precision);
|
||||
}
|
||||
|
||||
static gdouble
|
||||
gimp_stroke_real_get_length (const GimpStroke *stroke)
|
||||
gimp_stroke_real_get_length (const GimpStroke *stroke,
|
||||
const gdouble precision)
|
||||
{
|
||||
g_printerr ("gimp_stroke_get_length: default implementation\n");
|
||||
GArray *points;
|
||||
gint i;
|
||||
gdouble length;
|
||||
GimpCoords difference;
|
||||
|
||||
return 0.0;
|
||||
g_return_val_if_fail (GIMP_IS_STROKE (stroke), -1);
|
||||
|
||||
if (!stroke->anchors)
|
||||
return -1;
|
||||
|
||||
points = gimp_stroke_interpolate (stroke, precision, NULL);
|
||||
if (points == NULL)
|
||||
return -1;
|
||||
|
||||
length = 0;
|
||||
|
||||
for (i = 0; i < points->len - 1; i++ )
|
||||
{
|
||||
gimp_coords_difference (&(g_array_index (points, GimpCoords, i)),
|
||||
&(g_array_index (points, GimpCoords, i+1)),
|
||||
&difference);
|
||||
length += gimp_coords_length (&difference);
|
||||
}
|
||||
|
||||
g_array_free(points, TRUE);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1190,3 +1224,78 @@ gimp_stroke_real_control_points_get (const GimpStroke *stroke,
|
|||
|
||||
return ret_array;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_stroke_get_point_at_dist (const GimpStroke *stroke,
|
||||
const gdouble dist,
|
||||
const gdouble precision,
|
||||
GimpCoords *position,
|
||||
gdouble *gradient)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_STROKE (stroke), FALSE);
|
||||
|
||||
return GIMP_STROKE_GET_CLASS (stroke)->get_point_at_dist (stroke,
|
||||
dist,
|
||||
precision,
|
||||
position,
|
||||
gradient);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
gimp_stroke_real_get_point_at_dist (const GimpStroke *stroke,
|
||||
const gdouble dist,
|
||||
const gdouble precision,
|
||||
GimpCoords *position,
|
||||
gdouble *gradient)
|
||||
{
|
||||
GArray *points;
|
||||
gint i;
|
||||
gdouble length;
|
||||
gdouble segment_length;
|
||||
gboolean ret = FALSE;
|
||||
GimpCoords difference;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_STROKE (stroke), FALSE);
|
||||
|
||||
points = gimp_stroke_interpolate (stroke, precision, NULL);
|
||||
if (points == NULL)
|
||||
return ret;
|
||||
|
||||
length = 0;
|
||||
for (i=0; i < points->len - 1; i++)
|
||||
{
|
||||
gimp_coords_difference (&(g_array_index (points, GimpCoords , i)),
|
||||
&(g_array_index (points, GimpCoords , i+1)),
|
||||
&difference);
|
||||
segment_length = gimp_coords_length (&difference);
|
||||
|
||||
if (segment_length == 0 || length + segment_length < dist )
|
||||
{
|
||||
length += segment_length;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* x = x1 + (x2 - x1 ) u */
|
||||
/* x = x1 (1-u) + u x2 */
|
||||
|
||||
gdouble u = (dist - length) / segment_length;
|
||||
|
||||
gimp_coords_mix (1 - u, &(g_array_index (points, GimpCoords , i)),
|
||||
u, &(g_array_index (points, GimpCoords , i+1)),
|
||||
position);
|
||||
|
||||
if (difference.y == 0)
|
||||
*gradient = G_MAXDOUBLE;
|
||||
else
|
||||
*gradient = difference.x / difference.y;
|
||||
|
||||
ret = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_array_free (points, TRUE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -115,9 +115,15 @@ struct _GimpStrokeClass
|
|||
GimpAnchor *neighbor);
|
||||
|
||||
gboolean (* is_empty) (const GimpStroke *stroke);
|
||||
gdouble (* get_length) (const GimpStroke *stroke);
|
||||
gdouble (* get_length) (const GimpStroke *stroke,
|
||||
const gdouble precision);
|
||||
gdouble (* get_distance) (const GimpStroke *stroke,
|
||||
const GimpCoords *coord);
|
||||
gboolean (* get_point_at_dist) (const GimpStroke *stroke,
|
||||
const gdouble dist,
|
||||
const gdouble precision,
|
||||
GimpCoords *position,
|
||||
gdouble *gradient);
|
||||
|
||||
GArray * (* interpolate) (const GimpStroke *stroke,
|
||||
const gdouble precision,
|
||||
|
@ -237,13 +243,20 @@ gboolean gimp_stroke_is_empty (const GimpStroke *stroke);
|
|||
|
||||
/* accessing the shape of the curve */
|
||||
|
||||
gdouble gimp_stroke_get_length (const GimpStroke *stroke);
|
||||
gdouble gimp_stroke_get_length (const GimpStroke *stroke,
|
||||
const gdouble precision);
|
||||
gdouble gimp_stroke_get_distance (const GimpStroke *stroke,
|
||||
const GimpCoords *coord);
|
||||
|
||||
gboolean gimp_stroke_get_point_at_dist (const GimpStroke *stroke,
|
||||
const gdouble dist,
|
||||
const gdouble precision,
|
||||
GimpCoords *position,
|
||||
gdouble *gradient);
|
||||
|
||||
/* returns an array of valid coordinates */
|
||||
GArray * gimp_stroke_interpolate (const GimpStroke *stroke,
|
||||
gdouble precision,
|
||||
const gdouble precision,
|
||||
gboolean *closed);
|
||||
|
||||
GimpStroke * gimp_stroke_duplicate (const GimpStroke *stroke);
|
||||
|
@ -265,6 +278,5 @@ GList * gimp_stroke_get_draw_anchors (const GimpStroke *stroke);
|
|||
GList * gimp_stroke_get_draw_controls (const GimpStroke *stroke);
|
||||
GArray * gimp_stroke_get_draw_lines (const GimpStroke *stroke);
|
||||
|
||||
|
||||
#endif /* __GIMP_STROKE_H__ */
|
||||
|
||||
|
|
|
@ -353,18 +353,53 @@ HELP
|
|||
);
|
||||
|
||||
%invoke = (
|
||||
vars => [ 'GimpVectors *vectors' ],
|
||||
vars => [ 'GimpVectors *vectors', 'GimpStroke *stroke',
|
||||
'gdouble distance_along', 'gdouble stroke_length',
|
||||
'gdouble stroke_distance', 'GimpCoords position' ],
|
||||
code => <<'CODE'
|
||||
{
|
||||
vectors = gimp_image_get_active_vectors (gimage);
|
||||
|
||||
if (vectors)
|
||||
{
|
||||
g_warning ("FIXME: path_get_point_at_dist() is unimplemented");
|
||||
success = FALSE;
|
||||
distance_along = 0.0;
|
||||
stroke = gimp_vectors_stroke_get_next (vectors, NULL);
|
||||
|
||||
while (stroke != NULL )
|
||||
{
|
||||
stroke_length = gimp_stroke_get_length (stroke, 0.5);
|
||||
|
||||
if (distance_along + stroke_length < distance)
|
||||
{
|
||||
distance_along += stroke_length;
|
||||
}
|
||||
else
|
||||
{
|
||||
stroke_distance = distance - distance_along;
|
||||
stroke_distance = stroke_distance < 0 ? 0: stroke_distance;
|
||||
|
||||
if (!gimp_stroke_get_point_at_dist (stroke, stroke_distance, 0.5,
|
||||
&position, &gradient))
|
||||
{
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
success = TRUE;
|
||||
x_point = ROUND (position.x);
|
||||
y_point = ROUND (position.y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
stroke = gimp_vectors_stroke_get_next (vectors, stroke);
|
||||
}
|
||||
}
|
||||
else
|
||||
success = FALSE;
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
CODE
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue