curve.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /* curve.h: data structures for the conversion from pixels to splines.
  2. Copyright (C) 1992 Free Software Foundation, Inc.
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2, or (at your option)
  6. any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
  14. #ifndef CURVE_H
  15. #define CURVE_H
  16. #include "types.h"
  17. #include "vector.h"
  18. /* We are simultaneously manipulating two different representations of
  19. the same outline: one based on (x,y) positions in the plane, and one
  20. based on parametric splines. (We are trying to match the latter to
  21. the former.) Although the original (x,y)'s are pixel positions,
  22. i.e., integers, after filtering they are reals. */
  23. typedef struct
  24. {
  25. real_coordinate_type coord;
  26. real t;
  27. } point_type;
  28. /* It turns out to be convenient to break the list of all the pixels in
  29. the outline into sublists, divided at ``corners''. Then each of the
  30. sublists is treated independently. Each of these sublists is a `curve'. */
  31. struct curve
  32. {
  33. point_type *point_list;
  34. int length;
  35. boolean cyclic;
  36. vector_type *start_tangent;
  37. vector_type *end_tangent;
  38. struct curve *previous;
  39. struct curve *next;
  40. };
  41. typedef struct curve *curve_type;
  42. /* Get at the coordinates and the t values. */
  43. #define CURVE_POINT(c, n) ((c)->point_list[n].coord)
  44. #define LAST_CURVE_POINT(c) ((c)->point_list[(c)->length-1].coord)
  45. #define CURVE_T(c, n) ((c)->point_list[n].t)
  46. #define LAST_CURVE_T(c) ((c)->point_list[(c)->length-1].t)
  47. /* This is the length of `point_list'. */
  48. #define CURVE_LENGTH(c) ((c)->length)
  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. /* If the curve is cyclic, the next and previous points should wrap
  53. around; otherwise, if we get to the end, we return CURVE_LENGTH and
  54. -1, respectively. */
  55. #define CURVE_NEXT(c, n) \
  56. ((n) + 1 >= CURVE_LENGTH (c) \
  57. ? CURVE_CYCLIC (c) ? ((n) + 1) % CURVE_LENGTH (c) : CURVE_LENGTH (c) \
  58. : (n) + 1)
  59. #define CURVE_PREV(c, n) \
  60. ((int) (n) - 1 < 0 \
  61. ? CURVE_CYCLIC (c) ? CURVE_LENGTH (c) + (int) (n) - 1 : -1 \
  62. : (int) (n) - 1)
  63. /* The tangents at the endpoints are computed using the neighboring curves. */
  64. #define CURVE_START_TANGENT(c) ((c)->start_tangent)
  65. #define CURVE_END_TANGENT(c) ((c)->end_tangent)
  66. #define PREVIOUS_CURVE(c) ((c)->previous)
  67. #define NEXT_CURVE(c) ((c)->next)
  68. /* Return an entirely empty curve. */
  69. extern curve_type new_curve (void);
  70. /* Return a curve with the point P as its first element. */
  71. extern curve_type init_curve (coordinate_type p);
  72. /* Return a curve the same as C, except without any points. */
  73. extern curve_type copy_most_of_curve (curve_type c);
  74. /* Free the memory C uses. */
  75. extern void free_curve (curve_type c);
  76. /* Append the point P to the end of C's list. */
  77. extern void append_pixel (curve_type c, coordinate_type p);
  78. /* Like `append_pixel', for a point in real coordinates. */
  79. extern void append_point (curve_type c, real_coordinate_type p);
  80. /* Write some or all, respectively, of the curve C in human-readable
  81. form to the log file, if logging is enabled. */
  82. extern void log_curve (curve_type c, boolean print_t);
  83. extern void log_entire_curve (curve_type c);
  84. /* Display the curve C online, if displaying is enabled. */
  85. extern void display_curve (curve_type);
  86. /* So, an outline is a list of curves. */
  87. typedef struct
  88. {
  89. curve_type *data;
  90. unsigned length;
  91. boolean clockwise;
  92. } curve_list_type;
  93. /* Number of curves in the list. */
  94. #define CURVE_LIST_LENGTH(c_l) ((c_l).length)
  95. /* Access the individual curves. */
  96. #define CURVE_LIST_ELT(c_l, n) ((c_l).data[n])
  97. #define LAST_CURVE_LIST_ELT(c_l) ((c_l).data[CURVE_LIST_LENGTH (c_l) - 1])
  98. /* Says whether the outline that this curve list represents moves
  99. clockwise or counterclockwise. */
  100. #define CURVE_LIST_CLOCKWISE(c_l) ((c_l).clockwise)
  101. extern curve_list_type new_curve_list (void);
  102. extern void free_curve_list (curve_list_type *);
  103. extern void append_curve (curve_list_type *, curve_type);
  104. /* And a character is a list of outlines. I named this
  105. `curve_list_array_type' because `curve_list_list_type' seemed pretty
  106. monstrous. */
  107. typedef struct
  108. {
  109. curve_list_type *data;
  110. unsigned length;
  111. } curve_list_array_type;
  112. /* Turns out we can use the same definitions for lists of lists as for
  113. just lists. But we define the usual names, just in case. */
  114. #define CURVE_LIST_ARRAY_LENGTH CURVE_LIST_LENGTH
  115. #define CURVE_LIST_ARRAY_ELT CURVE_LIST_ELT
  116. #define LAST_CURVE_LIST_ARRAY_ELT LAST_CURVE_LIST_ELT
  117. extern curve_list_array_type new_curve_list_array (void);
  118. extern void free_curve_list_array (curve_list_array_type *);
  119. extern void append_curve_list (curve_list_array_type *, curve_list_type);
  120. #endif /* not CURVE_H */