1 /* curve.h: data structures for the conversion from pixels to splines. */
2 
3 #ifndef CURVE_H
4 #define CURVE_H
5 
6 #include "autotrace.h"
7 #include "vector.h"
8 
9 
10 /* We are simultaneously manipulating two different representations of
11    the same outline: one based on (x,y) positions in the plane, and one
12    based on parametric splines.  (We are trying to match the latter to
13    the former.)  Although the original (x,y)'s are pixel positions,
14    i.e., integers, after filtering they are reals.  */
15 
16 typedef struct
17 {
18   at_real_coord coord;
19   at_real t;
20 } point_type;
21 
22 
23 /* It turns out to be convenient to break the list of all the pixels in
24    the outline into sublists, divided at ``corners''.  Then each of the
25    sublists is treated independently.  Each of these sublists is a `curve'.  */
26 
27 struct curve
28 {
29   point_type *point_list;
30   unsigned length;
31   at_bool cyclic;
32   vector_type *start_tangent;
33   vector_type *end_tangent;
34   struct curve *previous;
35   struct curve *next;
36 };
37 
38 typedef struct curve *curve_type;
39 
40 /* Get at the coordinates and the t values.  */
41 #define CURVE_POINT(c, n) ((c)->point_list[n].coord)
42 #define LAST_CURVE_POINT(c) ((c)->point_list[(c)->length-1].coord)
43 #define CURVE_T(c, n) ((c)->point_list[n].t)
44 #define LAST_CURVE_T(c) ((c)->point_list[(c)->length-1].t)
45 
46 /* This is the length of `point_list'.  */
47 #define CURVE_LENGTH(c)  ((c)->length)
48 
49 /* A curve is ``cyclic'' if it didn't have any corners, after all, so
50    the last point is adjacent to the first.  */
51 #define CURVE_CYCLIC(c)  ((c)->cyclic)
52 
53 /* If the curve is cyclic, the next and previous points should wrap
54    around; otherwise, if we get to the end, we return CURVE_LENGTH and
55    -1, respectively.  */
56 #define CURVE_NEXT(c, n)						\
57   ((n) + 1 >= CURVE_LENGTH (c)						\
58   ? CURVE_CYCLIC (c) ? ((n) + 1) % CURVE_LENGTH (c) : CURVE_LENGTH (c)	\
59   : (n) + 1)
60 #define CURVE_PREV(c, n)						\
61   ((signed int) (n) - 1 < 0							\
62   ? CURVE_CYCLIC (c) ? (signed int) CURVE_LENGTH (c) + (signed int) (n) - 1 : -1\
63   : (signed int) (n) - 1)
64 
65 /* The tangents at the endpoints are computed using the neighboring curves.  */
66 #define CURVE_START_TANGENT(c) ((c)->start_tangent)
67 #define CURVE_END_TANGENT(c) ((c)->end_tangent)
68 #define PREVIOUS_CURVE(c) ((c)->previous)
69 #define NEXT_CURVE(c) ((c)->next)
70 
71 
72 /* Return an entirely empty curve.  */
73 extern curve_type new_curve (void);
74 
75 /* Return a curve the same as C, except without any points.  */
76 extern curve_type copy_most_of_curve (curve_type c);
77 
78 /* Free the memory C uses.  */
79 extern void free_curve (curve_type c);
80 
81 /* Append the point P to the end of C's list.  */
82 extern void append_pixel (curve_type c, at_coord p);
83 
84 /* Like `append_pixel', for a point in real coordinates.  */
85 extern void append_point (curve_type c, at_real_coord p);
86 
87 /* Write some or all, respectively, of the curve C in human-readable
88    form to the log file, if logging is enabled.  */
89 extern void log_curve (curve_type c, at_bool print_t);
90 extern void log_entire_curve (curve_type c);
91 
92 /* Display the curve C online, if displaying is enabled.  */
93 extern void display_curve (curve_type);
94 
95 /* So, an outline is a list of curves.  */
96 typedef struct
97 {
98   curve_type *data;
99   unsigned length;
100   at_bool clockwise;
101   at_bool open;
102 } curve_list_type;
103 
104 /* Number of curves in the list.  */
105 #define CURVE_LIST_LENGTH(c_l)  ((c_l).length)
106 
107 /* Access the individual curves.  */
108 #define CURVE_LIST_ELT(c_l, n) ((c_l).data[n])
109 #define LAST_CURVE_LIST_ELT(c_l) ((c_l).data[CURVE_LIST_LENGTH (c_l) - 1])
110 
111 /* Says whether the outline that this curve list represents moves
112    clockwise or counterclockwise.  */
113 #define CURVE_LIST_CLOCKWISE(c_l) ((c_l).clockwise)
114 
115 
116 extern curve_list_type new_curve_list (void);
117 extern void free_curve_list (curve_list_type *);
118 extern void append_curve (curve_list_type *, curve_type);
119 
120 /* And a character is a list of outlines.  I named this
121    `curve_list_array_type' because `curve_list_list_type' seemed pretty
122    monstrous.  */
123 typedef struct
124 {
125   curve_list_type *data;
126   unsigned length;
127 } curve_list_array_type;
128 
129 /* Turns out we can use the same definitions for lists of lists as for
130    just lists.  But we define the usual names, just in case.  */
131 #define CURVE_LIST_ARRAY_LENGTH CURVE_LIST_LENGTH
132 #define CURVE_LIST_ARRAY_ELT CURVE_LIST_ELT
133 #define LAST_CURVE_LIST_ARRAY_ELT LAST_CURVE_LIST_ELT
134 
135 extern curve_list_array_type new_curve_list_array (void);
136 extern void free_curve_list_array (curve_list_array_type *,
137 				   at_progress_func,
138 				   at_address);
139 extern void append_curve_list (curve_list_array_type *, curve_list_type);
140 
141 #endif /* not CURVE_H */
142 
143