mirror of https://github.com/GNOME/gimp.git
158 lines
5.2 KiB
C
158 lines
5.2 KiB
C
/* 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 2, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||
|
||
#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 */
|