gimp r27314 - in trunk: . app app/core app/vectors
- From: neo svn gnome org
- To: svn-commits-list gnome org
- Subject: gimp r27314 - in trunk: . app app/core app/vectors
- Date: Sat, 18 Oct 2008 18:46:15 +0000 (UTC)
Author: neo
Date: Sat Oct 18 18:46:15 2008
New Revision: 27314
URL: http://svn.gnome.org/viewvc/gimp?rev=27314&view=rev
Log:
2008-10-18 Sven Neumann <sven gimp org>
Applied patch from Alexia Death as attached to bug #471344:
* app/core/Makefile.am
* app/core/gimpcoords-interpolate.[ch]: new files with
interpolation code taken from ...
* app/vectors/gimpbezierstroke.c: ... here.
* app/Makefile.am (AM_LDFLAGS): make it link.
Added:
trunk/app/core/gimpcoords-interpolate.c
trunk/app/core/gimpcoords-interpolate.h
Modified:
trunk/ChangeLog
trunk/app/Makefile.am
trunk/app/core/Makefile.am
trunk/app/vectors/gimpbezierstroke.c
Modified: trunk/app/Makefile.am
==============================================================================
--- trunk/app/Makefile.am (original)
+++ trunk/app/Makefile.am Sat Oct 18 18:46:15 2008
@@ -99,7 +99,7 @@
$(CARBON_LDFLAGS) \
-u $(SYMPREFIX)xcf_init \
-u $(SYMPREFIX)internal_procs_init \
- -u $(SYMPREFIX)gimp_coords_mix \
+ -u $(SYMPREFIX)gimp_coords_interpolate_bezier \
-u $(SYMPREFIX)gimp_curve_map_pixels \
-u $(SYMPREFIX)gimp_image_map_config_get_type \
-u $(SYMPREFIX)gimp_plug_in_manager_restore
Modified: trunk/app/core/Makefile.am
==============================================================================
--- trunk/app/core/Makefile.am (original)
+++ trunk/app/core/Makefile.am Sat Oct 18 18:46:15 2008
@@ -88,6 +88,8 @@
gimpcontext.h \
gimpcoords.c \
gimpcoords.h \
+ gimpcoords-interpolate.c \
+ gimpcoords-interpolate.h \
gimpcurve.c \
gimpcurve.h \
gimpcurve-load.c \
Added: trunk/app/core/gimpcoords-interpolate.c
==============================================================================
--- (empty file)
+++ trunk/app/core/gimpcoords-interpolate.c Sat Oct 18 18:46:15 2008
@@ -0,0 +1,210 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpcoords-interpolate.c
+ *
+ * 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-1307, USA.
+ */
+
+#include "config.h"
+
+#include <glib-object.h>
+
+#include "libgimpmath/gimpmath.h"
+
+#include "core-types.h"
+
+#include "gimpcoords.h"
+#include "gimpcoords-interpolate.h"
+
+/* Local helper functions declarations*/
+static void gimp_coords_interpolate_bezier_internal (const GimpCoords bezier_pt1,
+ const GimpCoords bezier_pt2,
+ const GimpCoords bezier_pt3,
+ const GimpCoords bezier_pt4,
+ const gdouble start_t,
+ const gdouble end_t,
+ const gdouble precision,
+ GArray **ret_coords,
+ GArray **ret_params,
+ gint depth);
+
+/* Functions for bezier subdivision */
+
+void
+gimp_coords_interpolate_bezier (const GimpCoords bezier_pt1,
+ const GimpCoords bezier_pt2,
+ const GimpCoords bezier_pt3,
+ const GimpCoords bezier_pt4,
+ const gdouble precision,
+ GArray **ret_coords,
+ GArray **ret_params)
+{
+ gimp_coords_interpolate_bezier_internal (bezier_pt1,
+ bezier_pt2,
+ bezier_pt3,
+ bezier_pt4,
+ 0.0, 1.0,
+ precision,
+ ret_coords, ret_params, 10);
+}
+
+/* Recursive subdivision helper function */
+static void
+gimp_coords_interpolate_bezier_internal (const GimpCoords bezier_pt1,
+ const GimpCoords bezier_pt2,
+ const GimpCoords bezier_pt3,
+ const GimpCoords bezier_pt4,
+ const gdouble start_t,
+ const gdouble end_t,
+ const gdouble precision,
+ GArray **ret_coords,
+ GArray **ret_params,
+ gint depth)
+{
+ /*
+ * beziercoords has to contain four GimpCoords with the four control points
+ * of the bezier segment. We subdivide it at the parameter 0.5.
+ */
+
+ GimpCoords subdivided[8];
+ gdouble middle_t = (start_t + end_t) / 2;
+
+ subdivided[0] = bezier_pt1;
+ subdivided[6] = bezier_pt4;
+
+ /* if (!depth) g_printerr ("Hit recursion depth limit!\n"); */
+
+ gimp_coords_average (&bezier_pt1, &bezier_pt2, &(subdivided[1]));
+
+ gimp_coords_average (&bezier_pt2, &bezier_pt3, &(subdivided[7]));
+
+ gimp_coords_average (&bezier_pt3, &bezier_pt4, &(subdivided[5]));
+
+ gimp_coords_average (&(subdivided[1]), &(subdivided[7]),
+ &(subdivided[2]));
+
+ gimp_coords_average (&(subdivided[7]), &(subdivided[5]),
+ &(subdivided[4]));
+
+ gimp_coords_average (&(subdivided[2]), &(subdivided[4]),
+ &(subdivided[3]));
+
+ /*
+ * We now have the coordinates of the two bezier segments in
+ * subdivided [0-3] and subdivided [3-6]
+ */
+
+ /*
+ * Here we need to check, if we have sufficiently subdivided, i.e.
+ * if the stroke is sufficiently close to a straight line.
+ */
+
+ if (!depth || gimp_coords_bezier_is_straight (subdivided[0],
+ subdivided[1],
+ subdivided[2],
+ subdivided[3],
+ precision)) /* 1st half */
+ {
+ *ret_coords = g_array_append_vals (*ret_coords, &(subdivided[0]), 3);
+
+ if (ret_params)
+ {
+ gdouble params[3];
+
+ params[0] = start_t;
+ params[1] = (2 * start_t + middle_t) / 3;
+ params[2] = (start_t + 2 * middle_t) / 3;
+
+ *ret_params = g_array_append_vals (*ret_params, &(params[0]), 3);
+ }
+ }
+ else
+ {
+ gimp_coords_interpolate_bezier_internal (subdivided[0],
+ subdivided[1],
+ subdivided[2],
+ subdivided[3],
+ start_t, (start_t + end_t) / 2,
+ precision,
+ ret_coords, ret_params, depth-1);
+ }
+
+ if (!depth || gimp_coords_bezier_is_straight (subdivided[3],
+ subdivided[4],
+ subdivided[5],
+ subdivided[6],
+ precision)) /* 2nd half */
+ {
+ *ret_coords = g_array_append_vals (*ret_coords, &(subdivided[3]), 3);
+
+ if (ret_params)
+ {
+ gdouble params[3];
+
+ params[0] = middle_t;
+ params[1] = (2 * middle_t + end_t) / 3;
+ params[2] = (middle_t + 2 * end_t) / 3;
+
+ *ret_params = g_array_append_vals (*ret_params, &(params[0]), 3);
+ }
+ }
+ else
+ {
+ gimp_coords_interpolate_bezier_internal (subdivided[3],
+ subdivided[4],
+ subdivided[5],
+ subdivided[6],
+ (start_t + end_t) / 2, end_t,
+ precision,
+ ret_coords, ret_params, depth-1);
+ }
+}
+
+
+/*
+ * a helper function that determines if a bezier segment is "straight
+ * enough" to be approximated by a line.
+ *
+ * To be more exact, it also checks for the control points to be distributed
+ * evenly along the line. This makes it easier to reconstruct parameters for
+ * a given point along the segment.
+ *
+ * Needs four GimpCoords in an array.
+ */
+
+gboolean
+gimp_coords_bezier_is_straight (const GimpCoords bezier_pt1,
+ const GimpCoords bezier_pt2,
+ const GimpCoords bezier_pt3,
+ const GimpCoords bezier_pt4,
+ gdouble precision)
+{
+ GimpCoords pt1, pt2;
+
+ /* calculate the "ideal" positions for the control points */
+
+ gimp_coords_mix (2.0 / 3.0, &bezier_pt1,
+ 1.0 / 3.0, &bezier_pt4,
+ &pt1);
+ gimp_coords_mix (1.0 / 3.0, &bezier_pt1,
+ 2.0 / 3.0, &bezier_pt4,
+ &pt2);
+
+ /* calculate the deviation of the actual control points */
+
+ return (gimp_coords_manhattan_dist (&bezier_pt2, &pt1) < precision &&
+ gimp_coords_manhattan_dist (&bezier_pt3, &pt2) < precision);
+}
Added: trunk/app/core/gimpcoords-interpolate.h
==============================================================================
--- (empty file)
+++ trunk/app/core/gimpcoords-interpolate.h Sat Oct 18 18:46:15 2008
@@ -0,0 +1,38 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpcoords-interpolate.h
+ *
+ * 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-1307, USA.
+ */
+
+#ifndef __GIMP_COORDS_INTERPOLATE_H__
+#define __GIMP_COORDS_INTERPOLATE_H__
+
+void gimp_coords_interpolate_bezier (const GimpCoords bezier_pt1,
+ const GimpCoords bezier_pt2,
+ const GimpCoords bezier_pt3,
+ const GimpCoords bezier_pt4,
+ gdouble precision,
+ GArray **ret_coords,
+ GArray **ret_params);
+
+gboolean gimp_coords_bezier_is_straight (const GimpCoords bezier_pt1,
+ const GimpCoords bezier_pt2,
+ const GimpCoords bezier_pt3,
+ const GimpCoords bezier_pt4,
+ gdouble precision);
+
+#endif /* __GIMP_COORDS_INTERPOLATE_H__ */
Modified: trunk/app/vectors/gimpbezierstroke.c
==============================================================================
--- trunk/app/vectors/gimpbezierstroke.c (original)
+++ trunk/app/vectors/gimpbezierstroke.c Sat Oct 18 18:46:15 2008
@@ -29,6 +29,7 @@
#include "vectors-types.h"
#include "core/gimpcoords.h"
+#include "core/gimpcoords-interpolate.h"
#include "gimpanchor.h"
#include "gimpbezierstroke.h"
@@ -140,22 +141,6 @@
static GList * gimp_bezier_stroke_get_anchor_listitem
(GList *list);
-static void gimp_bezier_coords_subdivide (const GimpCoords *beziercoords,
- const gdouble precision,
- GArray **ret_coords,
- GArray **ret_params);
-static void gimp_bezier_coords_subdivide2 (const GimpCoords *beziercoords,
- const gdouble start_t,
- const gdouble end_t,
- const gdouble precision,
- GArray **ret_coords,
- GArray **ret_params,
- gint depth);
-
-static gboolean gimp_bezier_coords_is_straight
- (const GimpCoords *beziercoords,
- const gdouble precision);
-
G_DEFINE_TYPE (GimpBezierStroke, gimp_bezier_stroke, GIMP_TYPE_STROKE)
@@ -691,7 +676,11 @@
gimp_coords_difference (&beziercoords[1], &beziercoords[0], &point1);
gimp_coords_difference (&beziercoords[3], &beziercoords[2], &point2);
- if (!depth || (gimp_bezier_coords_is_straight (beziercoords, precision)
+ if (!depth || (gimp_coords_bezier_is_straight (beziercoords[0],
+ beziercoords[1],
+ beziercoords[2],
+ beziercoords[3],
+ precision)
&& gimp_coords_length_squared (&point1) < precision
&& gimp_coords_length_squared (&point2) < precision))
{
@@ -924,8 +913,12 @@
g_printerr ("(%.2f, %.2f)-(%.2f,%.2f): ", coord1->x, coord1->y,
coord2->x, coord2->y);
- gimp_bezier_coords_subdivide (beziercoords, precision,
- &ret_coords, &ret_params);
+ gimp_coords_interpolate_bezier (beziercoords[0],
+ beziercoords[1],
+ beziercoords[2],
+ beziercoords[3],
+ precision,
+ &ret_coords, &ret_params);
g_return_val_if_fail (ret_coords->len == ret_params->len, -1.0);
@@ -1591,8 +1584,12 @@
if (count == 4)
{
- gimp_bezier_coords_subdivide (segmentcoords, precision,
- &ret_coords, NULL);
+ gimp_coords_interpolate_bezier (segmentcoords[0],
+ segmentcoords[1],
+ segmentcoords[2],
+ segmentcoords[3],
+ precision,
+ &ret_coords, NULL);
segmentcoords[0] = segmentcoords[3];
count = 1;
need_endpoint = TRUE;
@@ -1612,8 +1609,12 @@
if (anchorlist)
segmentcoords[3] = GIMP_ANCHOR (anchorlist->data)->position;
- gimp_bezier_coords_subdivide (segmentcoords, precision,
- &ret_coords, NULL);
+ gimp_coords_interpolate_bezier (segmentcoords[0],
+ segmentcoords[1],
+ segmentcoords[2],
+ segmentcoords[3],
+ precision,
+ &ret_coords, NULL);
need_endpoint = TRUE;
}
@@ -2110,149 +2111,3 @@
return NULL;
}
-
-
-/*
- * a helper function that determines if a bezier segment is "straight
- * enough" to be approximated by a line.
- *
- * To be more exact, it also checks for the control points to be distributed
- * evenly along the line. This makes it easier to reconstruct parameters for
- * a given point along the segment.
- *
- * Needs four GimpCoords in an array.
- */
-
-static gboolean
-gimp_bezier_coords_is_straight (const GimpCoords *beziercoords,
- gdouble precision)
-{
- GimpCoords pt1, pt2;
-
- /* calculate the "ideal" positions for the control points */
-
- gimp_coords_mix (2.0 / 3.0, &(beziercoords[0]),
- 1.0 / 3.0, &(beziercoords[3]),
- &pt1);
- gimp_coords_mix (1.0 / 3.0, &(beziercoords[0]),
- 2.0 / 3.0, &(beziercoords[3]),
- &pt2);
-
- /* calculate the deviation of the actual control points */
-
- return (gimp_coords_manhattan_dist (&(beziercoords[1]), &pt1) < precision &&
- gimp_coords_manhattan_dist (&(beziercoords[2]), &pt2) < precision);
-}
-
-
-/* local helper functions for bezier subdivision */
-
-static void
-gimp_bezier_coords_subdivide (const GimpCoords *beziercoords,
- const gdouble precision,
- GArray **ret_coords,
- GArray **ret_params)
-{
- gimp_bezier_coords_subdivide2 (beziercoords, 0.0, 1.0,
- precision, ret_coords, ret_params, 10);
-}
-
-
-static void
-gimp_bezier_coords_subdivide2 (const GimpCoords *beziercoords,
- const gdouble start_t,
- const gdouble end_t,
- const gdouble precision,
- GArray **ret_coords,
- GArray **ret_params,
- gint depth)
-{
- /*
- * beziercoords has to contain four GimpCoords with the four control points
- * of the bezier segment. We subdivide it at the parameter 0.5.
- */
-
- GimpCoords subdivided[8];
- gdouble middle_t = (start_t + end_t) / 2;
-
- subdivided[0] = beziercoords[0];
- subdivided[6] = beziercoords[3];
-
- /* if (!depth) g_printerr ("Hit recursion depth limit!\n"); */
-
- gimp_coords_average (&(beziercoords[0]), &(beziercoords[1]),
- &(subdivided[1]));
-
- gimp_coords_average (&(beziercoords[1]), &(beziercoords[2]),
- &(subdivided[7]));
-
- gimp_coords_average (&(beziercoords[2]), &(beziercoords[3]),
- &(subdivided[5]));
-
- gimp_coords_average (&(subdivided[1]), &(subdivided[7]),
- &(subdivided[2]));
-
- gimp_coords_average (&(subdivided[7]), &(subdivided[5]),
- &(subdivided[4]));
-
- gimp_coords_average (&(subdivided[2]), &(subdivided[4]),
- &(subdivided[3]));
-
- /*
- * We now have the coordinates of the two bezier segments in
- * subdivided [0-3] and subdivided [3-6]
- */
-
- /*
- * Here we need to check, if we have sufficiently subdivided, i.e.
- * if the stroke is sufficiently close to a straight line.
- */
-
- if (!depth || gimp_bezier_coords_is_straight (&(subdivided[0]),
- precision)) /* 1st half */
- {
- *ret_coords = g_array_append_vals (*ret_coords, &(subdivided[0]), 3);
-
- if (ret_params)
- {
- gdouble params[3];
-
- params[0] = start_t;
- params[1] = (2 * start_t + middle_t) / 3;
- params[2] = (start_t + 2 * middle_t) / 3;
-
- *ret_params = g_array_append_vals (*ret_params, &(params[0]), 3);
- }
- }
- else
- {
- gimp_bezier_coords_subdivide2 (&(subdivided[0]),
- start_t, (start_t + end_t) / 2,
- precision,
- ret_coords, ret_params, depth-1);
- }
-
- if (!depth || gimp_bezier_coords_is_straight (&(subdivided[3]),
- precision)) /* 2nd half */
- {
- *ret_coords = g_array_append_vals (*ret_coords, &(subdivided[3]), 3);
-
- if (ret_params)
- {
- gdouble params[3];
-
- params[0] = middle_t;
- params[1] = (2 * middle_t + end_t) / 3;
- params[2] = (middle_t + 2 * end_t) / 3;
-
- *ret_params = g_array_append_vals (*ret_params, &(params[0]), 3);
- }
- }
- else
- {
- gimp_bezier_coords_subdivide2 (&(subdivided[3]),
- (start_t + end_t) / 2, end_t,
- precision,
- ret_coords, ret_params, depth-1);
- }
-}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]