curve.c 4.43 KB
Newer Older
1
/* curve.c: operations on the lists of pixels and lists of curves.
Sven Neumann's avatar
Sven Neumann committed
2 3 4
 *
 * Copyright (C) 1992 Free Software Foundation, Inc.
 *
5
 * This program is free software: you can redistribute it and/or modify
Sven Neumann's avatar
Sven Neumann committed
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 3, or (at your option)
Sven Neumann's avatar
Sven Neumann committed
8 9 10 11 12 13 14 15
 * 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
16
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
Sven Neumann's avatar
Sven Neumann committed
17
 */
18

19 20
#include "config.h"

21
#include <glib.h>
22 23 24 25 26 27 28 29

#include "global.h"
#include "curve.h"


/* Return an entirely empty curve.  */

curve_type
30
new_curve (void)
31
{
32
  curve_type curve = g_new (struct curve, 1);
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

  curve->point_list = NULL;
  CURVE_LENGTH (curve) = 0;
  CURVE_CYCLIC (curve) = false;
  CURVE_START_TANGENT (curve) = CURVE_END_TANGENT (curve) = NULL;
  PREVIOUS_CURVE (curve) = NEXT_CURVE (curve) = NULL;

  return curve;
}


/* Start the returned curve off with COORD as the first point.  */

curve_type
init_curve (coordinate_type coord)
{
  curve_type curve = new_curve ();

51
  curve->point_list = g_new (point_type, 1);
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
  CURVE_LENGTH (curve) = 1;

  CURVE_POINT (curve, 0) = int_to_real_coord (coord);

  return curve;
}


/* Don't copy the points or tangents, but copy everything else.  */

curve_type
copy_most_of_curve (curve_type old_curve)
{
  curve_type curve = new_curve ();

  CURVE_CYCLIC (curve) = CURVE_CYCLIC (old_curve);
  PREVIOUS_CURVE (curve) = PREVIOUS_CURVE (old_curve);
  NEXT_CURVE (curve) = NEXT_CURVE (old_curve);

  return curve;
}


/* The length of CURVE will be zero if we ended up not being able to fit
   it (which in turn implies a problem elsewhere in the program, but at
   any rate, we shouldn't try here to free the nonexistent curve).  */

void
free_curve (curve_type curve)
{
  if (CURVE_LENGTH (curve) > 0)
    safe_free ((address *) &(curve->point_list));
}


void
append_pixel (curve_type curve, coordinate_type coord)
{
  append_point (curve, int_to_real_coord (coord));
}


void
append_point (curve_type curve, real_coordinate_type coord)
{
  CURVE_LENGTH (curve)++;
98
  curve->point_list = g_realloc (curve->point_list,CURVE_LENGTH (curve) * sizeof(point_type));
99 100 101 102 103 104 105
  LAST_CURVE_POINT (curve) = coord;
  /* The t value does not need to be set.  */
}

/* Return an initialized but empty curve list.  */

curve_list_type
106
new_curve_list (void)
107 108 109
{
  curve_list_type curve_list;

110 111 112
  curve_list.length    = 0;
  curve_list.data      = NULL;
  curve_list.clockwise = FALSE;
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139

  return curve_list;
}


/* Free a curve list and all the curves it contains.  */

void
free_curve_list (curve_list_type *curve_list)
{
  unsigned this_curve;

  for (this_curve = 0; this_curve < curve_list->length; this_curve++)
    free_curve (curve_list->data[this_curve]);

  /* If the character was empty, it won't have any curves.  */
  if (curve_list->data != NULL)
    safe_free ((address *) &(curve_list->data));
}


/* Add an element to a curve list.  */

void
append_curve (curve_list_type *curve_list, curve_type curve)
{
  curve_list->length++;
140
  curve_list->data = g_realloc (curve_list->data,curve_list->length*sizeof(curve_type));
141 142 143 144 145 146 147
  curve_list->data[curve_list->length - 1] = curve;
}


/* Return an initialized but empty curve list array.  */

curve_list_array_type
148
new_curve_list_array (void)
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
{
  curve_list_array_type curve_list_array;

  CURVE_LIST_ARRAY_LENGTH (curve_list_array) = 0;
  curve_list_array.data = NULL;

  return curve_list_array;
}


/* Free a curve list array and all the curve lists it contains.  */

void
free_curve_list_array (curve_list_array_type *curve_list_array)
{
  unsigned this_list;

  for (this_list = 0; this_list < CURVE_LIST_ARRAY_LENGTH (*curve_list_array);
167
       this_list++)
168 169 170 171 172 173 174 175 176 177 178 179 180 181
    free_curve_list (&CURVE_LIST_ARRAY_ELT (*curve_list_array, this_list));

  /* If the character was empty, it won't have any curves.  */
  if (curve_list_array->data != NULL)
    safe_free ((address *) &(curve_list_array->data));
}


/* Add an element to a curve list array.  */

void
append_curve_list (curve_list_array_type *l, curve_list_type curve_list)
{
  CURVE_LIST_ARRAY_LENGTH (*l)++;
182
  l->data = g_realloc (l->data,( CURVE_LIST_ARRAY_LENGTH (*l))*sizeof(curve_list_type));
183 184
  LAST_CURVE_LIST_ARRAY_ELT (*l) = curve_list;
}