diff options
Diffstat (limited to 'src/3rdparty/autotrace/curve.h')
-rw-r--r-- | src/3rdparty/autotrace/curve.h | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/src/3rdparty/autotrace/curve.h b/src/3rdparty/autotrace/curve.h new file mode 100644 index 0000000..1efcf4e --- /dev/null +++ b/src/3rdparty/autotrace/curve.h @@ -0,0 +1,131 @@ +/* curve.h: data structures for the conversion from pixels to splines. */ + +#ifndef CURVE_H +#define CURVE_H + +#include "autotrace.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 { + at_real_coord coord; + gfloat 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; + unsigned length; + gboolean 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) \ + ((signed int) (n) - 1 < 0 \ + ? CURVE_CYCLIC (c) ? (signed int) CURVE_LENGTH (c) + (signed int) (n) - 1 : -1\ + : (signed 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 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, at_coord p); + +/* Like `append_pixel', for a point in real coordinates. */ +extern void append_point(curve_type c, at_real_coord 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, gboolean 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; + gboolean clockwise; + gboolean open; +} 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 *, at_progress_func, gpointer); +extern void append_curve_list(curve_list_array_type *, curve_list_type); + +#endif /* not CURVE_H */ |