summaryrefslogtreecommitdiffstats
path: root/plug-ins/selection-to-path/curve.h
diff options
context:
space:
mode:
Diffstat (limited to 'plug-ins/selection-to-path/curve.h')
-rw-r--r--plug-ins/selection-to-path/curve.h157
1 files changed, 157 insertions, 0 deletions
diff --git a/plug-ins/selection-to-path/curve.h b/plug-ins/selection-to-path/curve.h
new file mode 100644
index 0000000..b0bd374
--- /dev/null
+++ b/plug-ins/selection-to-path/curve.h
@@ -0,0 +1,157 @@
+/* curve.h: data structures for the conversion from pixels to splines.
+ *
+ * Copyright (C) 1992 Free Software Foundation, Inc.
+ *
+ * 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 3, 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, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef CURVE_H
+#define CURVE_H
+
+#include "types.h"
+#include "vector.h"
+
+
+/* We are simultaneously manipulating two different representations of
+ the same outline: one based on (x,y) positions in the plane, and one
+ based on parametric splines. (We are trying to match the latter to
+ the former.) Although the original (x,y)'s are pixel positions,
+ i.e., integers, after filtering they are reals. */
+
+typedef struct
+{
+ real_coordinate_type coord;
+ real t;
+} point_type;
+
+
+/* It turns out to be convenient to break the list of all the pixels in
+ the outline into sublists, divided at ``corners''. Then each of the
+ sublists is treated independently. Each of these sublists is a `curve'. */
+
+struct curve
+{
+ point_type *point_list;
+ int length;
+ boolean cyclic;
+ vector_type *start_tangent;
+ vector_type *end_tangent;
+ struct curve *previous;
+ struct curve *next;
+};
+
+typedef struct curve *curve_type;
+
+/* Get at the coordinates and the t values. */
+#define CURVE_POINT(c, n) ((c)->point_list[n].coord)
+#define LAST_CURVE_POINT(c) ((c)->point_list[(c)->length-1].coord)
+#define CURVE_T(c, n) ((c)->point_list[n].t)
+#define LAST_CURVE_T(c) ((c)->point_list[(c)->length-1].t)
+
+/* This is the length of `point_list'. */
+#define CURVE_LENGTH(c) ((c)->length)
+
+/* A curve is ``cyclic'' if it didn't have any corners, after all, so
+ the last point is adjacent to the first. */
+#define CURVE_CYCLIC(c) ((c)->cyclic)
+
+/* If the curve is cyclic, the next and previous points should wrap
+ around; otherwise, if we get to the end, we return CURVE_LENGTH and
+ -1, respectively. */
+#define CURVE_NEXT(c, n) \
+ ((n) + 1 >= CURVE_LENGTH (c) \
+ ? CURVE_CYCLIC (c) ? ((n) + 1) % CURVE_LENGTH (c) : CURVE_LENGTH (c) \
+ : (n) + 1)
+#define CURVE_PREV(c, n) \
+ ((int) (n) - 1 < 0 \
+ ? CURVE_CYCLIC (c) ? CURVE_LENGTH (c) + (int) (n) - 1 : -1 \
+ : (int) (n) - 1)
+
+/* The tangents at the endpoints are computed using the neighboring curves. */
+#define CURVE_START_TANGENT(c) ((c)->start_tangent)
+#define CURVE_END_TANGENT(c) ((c)->end_tangent)
+#define PREVIOUS_CURVE(c) ((c)->previous)
+#define NEXT_CURVE(c) ((c)->next)
+
+
+/* Return an entirely empty curve. */
+extern curve_type new_curve (void);
+
+/* Return a curve with the point P as its first element. */
+extern curve_type init_curve (coordinate_type p);
+
+/* Return a curve the same as C, except without any points. */
+extern curve_type copy_most_of_curve (curve_type c);
+
+/* Free the memory C uses. */
+extern void free_curve (curve_type c);
+
+/* Append the point P to the end of C's list. */
+extern void append_pixel (curve_type c, coordinate_type p);
+
+/* Like `append_pixel', for a point in real coordinates. */
+extern void append_point (curve_type c, real_coordinate_type p);
+
+/* Write some or all, respectively, of the curve C in human-readable
+ form to the log file, if logging is enabled. */
+extern void log_curve (curve_type c, boolean print_t);
+extern void log_entire_curve (curve_type c);
+
+/* Display the curve C online, if displaying is enabled. */
+extern void display_curve (curve_type);
+
+/* So, an outline is a list of curves. */
+typedef struct
+{
+ curve_type *data;
+ unsigned length;
+ boolean clockwise;
+} curve_list_type;
+
+/* Number of curves in the list. */
+#define CURVE_LIST_LENGTH(c_l) ((c_l).length)
+
+/* Access the individual curves. */
+#define CURVE_LIST_ELT(c_l, n) ((c_l).data[n])
+#define LAST_CURVE_LIST_ELT(c_l) ((c_l).data[CURVE_LIST_LENGTH (c_l) - 1])
+
+/* Says whether the outline that this curve list represents moves
+ clockwise or counterclockwise. */
+#define CURVE_LIST_CLOCKWISE(c_l) ((c_l).clockwise)
+
+
+extern curve_list_type new_curve_list (void);
+extern void free_curve_list (curve_list_type *);
+extern void append_curve (curve_list_type *, curve_type);
+
+/* And a character is a list of outlines. I named this
+ `curve_list_array_type' because `curve_list_list_type' seemed pretty
+ monstrous. */
+typedef struct
+{
+ curve_list_type *data;
+ unsigned length;
+} curve_list_array_type;
+
+/* Turns out we can use the same definitions for lists of lists as for
+ just lists. But we define the usual names, just in case. */
+#define CURVE_LIST_ARRAY_LENGTH CURVE_LIST_LENGTH
+#define CURVE_LIST_ARRAY_ELT CURVE_LIST_ELT
+#define LAST_CURVE_LIST_ARRAY_ELT LAST_CURVE_LIST_ELT
+
+extern curve_list_array_type new_curve_list_array (void);
+extern void free_curve_list_array (curve_list_array_type *);
+extern void append_curve_list (curve_list_array_type *, curve_list_type);
+
+#endif /* not CURVE_H */