Example #1
0
/*
 * read the file into a list of lines.
 *
 * we use the buffered read functions to read a block at a time, and
 * return us a pointer to a line within the block. The line we are
 * pointed to is not null terminated. from this we do a line_new: this
 * will make a copy of the text (since we want to re-use the buffer), and
 * will null-terminate its copy.
 *
 * we also give each line a number, starting at one.
 */
void
file_readlines(FILEDATA fd)
{
    LPSTR textp;
    LPWSTR pwzText;
    int cwch;
    HANDLE fh;
    FILEBUFFER fbuf;
    int linelen;
    int linenr = 1;
    HCURSOR hcurs;

    hcurs = SetCursor(LoadCursor(NULL, IDC_WAIT));

    /* open the file */
    fh = dir_openfile(fd->diritem);

    if (fh == INVALID_HANDLE_VALUE) {
        TRACE_ERROR(LoadRcString(IDS_ERR_OPENING_FILE), FALSE);
        SetCursor(hcurs);
        return;
    }
    /* initialise the file buffering */
    fbuf = readfile_new(fh, &fd->fUnicode);

    if (fbuf)
    {
        /* make an empty list for the files */
        fd->lines = List_Create();

        while ( (textp = readfile_next(fbuf, &linelen, &pwzText, &cwch)) != NULL) {
            if (linelen>0) { /* readfile failure gives linelen==-1 */
                line_new(textp, linelen, pwzText, cwch, linenr++, fd->lines);
            } else {
                line_new("!! <unreadable> !!", 20, NULL, 0, linenr++,fd->lines);
                break;
            }


        }

        /* close filehandle and free buffer */
        readfile_delete(fbuf);
    }

    dir_closefile(fd->diritem, fh);

    SetCursor(hcurs);
}
Example #2
0
int main( int argc, char ** argv )
{
	line_t * ptr;
	int sz;

	char * lines[3] = {
		"goober",
		"",
		"Looks like a real line.\n"
	};
	for(int i=0; i < 3; i++)
	{
		ptr = line_new();
		line_set(ptr , lines[i]);	
		sz = line_size( ptr );
		printf("ptr size: %d\n", sz );
		printf("ptr data: %s\n", line_get(ptr) );
		printf("ends in newline: %s\n", line_has_newline( ptr ) ? "Yes" : "No"  );	
		printf("null terminated: %s\n", line_null_terminated( ptr ) ? "Yes" : "No" );	
		line_free( ptr );
		printf("line after free is null? %s\n", ptr == NULL ? "Yes" : "No" );	
	}

	return 0;
}
Example #3
0
bool buf_read(struct Buffer *buf, const char *name)
{
    buf_clear(buf);
    FILE *fp = fopen(name ?: buf->name, "r");
    if (fp) {
        char in[BUFSIZ];
        while (fgets(in, BUFSIZ, fp) != NULL) {
            struct Line *l = line_new(in, strlen(in) - 1);
            buf_pushback(buf, l);
        }
        buf->line = buf->beg;
        fclose(fp);
        return true;
    }
    else {
        struct Line *l = line_new(NULL, 0);
        buf_pushback(buf, l);
        buf->line = l;
    }
    return false;
}
Example #4
0
File: info.c Project: 111X/radare
static GObject * radare_gui_radget_information_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties) {
	GObject * obj;
	RadareGUIRadgetInformationClass * klass;
	GObjectClass * parent_class;
	RadareGUIRadgetInformation * self;
	klass = RADARE_GUI_RADGET_INFORMATION_CLASS (g_type_class_peek (RADARE_GUI_TYPE_RADGET_INFORMATION));
	parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = RADARE_GUI_RADGET_INFORMATION (obj);
	{
		GtkVBox* _tmp0;
		Line* _tmp2;
		Line* _tmp1;
		Line* _tmp4;
		Line* _tmp3;
		_tmp0 = NULL;
#line 14 "info.vala"
		self->priv->vb = (_tmp0 = g_object_ref_sink (((GtkVBox*) (gtk_vbox_new (FALSE, 2)))), (self->priv->vb == NULL ? NULL : (self->priv->vb = (g_object_unref (self->priv->vb), NULL))), _tmp0);
		_tmp2 = NULL;
		_tmp1 = NULL;
#line 15 "info.vala"
		self->priv->file = (_tmp2 = line_name ((_tmp1 = g_object_ref_sink (line_new ())), "File", "/bin/ls"), (self->priv->file == NULL ? NULL : (self->priv->file = (g_object_unref (self->priv->file), NULL))), _tmp2);
		(_tmp1 == NULL ? NULL : (_tmp1 = (g_object_unref (_tmp1), NULL)));
#line 16 "info.vala"
		gtk_container_add (((GtkContainer*) (self->priv->vb)), ((GtkWidget*) (self->priv->file)));
		_tmp4 = NULL;
		_tmp3 = NULL;
#line 17 "info.vala"
		self->priv->size = (_tmp4 = line_numeric ((_tmp3 = g_object_ref_sink (line_new ())), "Size", 38432), (self->priv->size == NULL ? NULL : (self->priv->size = (g_object_unref (self->priv->size), NULL))), _tmp4);
		(_tmp3 == NULL ? NULL : (_tmp3 = (g_object_unref (_tmp3), NULL)));
#line 18 "info.vala"
		gtk_container_add (((GtkContainer*) (self->priv->vb)), ((GtkWidget*) (self->priv->size)));
#line 19 "info.vala"
		radare_gui_radget_refresh (((RadareGUIRadget*) (self)));
	}
	return obj;
}
bool
c_DiffusionCurve::calculate_shadow(const t_Real _t_begin,
                                   const t_Real _t_end,
                                   const e_DirectionType _direction,
                                   const cv::Mat &_image,
                                   t_CvPointSet &_shadow) const
{
    _shadow.clear();

    t_Real length = m_p_curve->GetLength(_t_begin, _t_end);
    int n_segments = (std::max)(m_unit, length) / m_unit;
    t_Real dt = (_t_end - _t_begin) / n_segments;

    t_Point p_off_new = get_offset_point(_t_begin, _direction);
    t_Point p_on_new = m_p_curve->GetPosition(_t_begin);
    t_Point p_off_old, p_on_old;

    for (t_Real t = _t_begin; t < _t_end; t += dt)
    {
        p_off_old = p_off_new;
        p_on_old = p_on_new;
        p_on_new = m_p_curve->GetPosition(t + dt);
        p_off_new = get_offset_point(t + dt, _direction);
        t_Line line_old(p_on_old, p_off_old);
        t_Line line_new(p_on_new, p_off_new);
        t_Intersector intersection(line_old, line_new);
        /*!< if the two lines are not interstected */
        if (1 != intersection.GetQuantity())
        {
            t_CvPointSet temp_sequence;
            if (find_line_pixels(_image,
                                 t_CvPoint(p_off_old.X(), p_off_old.Y()),
                                 t_CvPoint(p_off_new.X(), p_off_new.Y()),
                                 temp_sequence))
            {
                _shadow.insert(_shadow.end(), temp_sequence.begin(),
                               temp_sequence.end() - 1);
            }
        }
    }
    /*!< append the last point into the sequence */
    _shadow.push_back(cv::Point(p_off_new.X(), p_off_new.Y()));

    return _shadow.size();
}
Example #6
0
static void screen_scroll_up(struct tsm_screen *con, unsigned int num)
{
	unsigned int i, j, max;
	int ret;

	if (!num)
		return;

	max = con->margin_bottom + 1 - con->margin_top;
	if (num > max)
		num = max;

	/* We cache lines on the stack to speed up the scrolling. However, if
	 * num is too big we might get overflows here so use recursion if num
	 * exceeds a hard-coded limit.
	 * 128 seems to be a sane limit that should never be reached but should
	 * also be small enough so we do not get stack overflows. */
	if (num > 128) {
		screen_scroll_up(con, 128);
		return screen_scroll_up(con, num - 128);
	}
	struct line *cache[num];

	for (i = 0; i < num; ++i) {
		ret = line_new(con, &cache[i], con->size_x);
		if (!ret) {
			link_to_scrollback(con,
					   con->lines[con->margin_top + i]);
		} else {
			cache[i] = con->lines[con->margin_top + i];
			for (j = 0; j < con->size_x; ++j)
				cell_init(con, &cache[i]->cells[j]);
		}
	}

	if (num < max) {
		memmove(&con->lines[con->margin_top],
			&con->lines[con->margin_top + num],
			(max - num) * sizeof(struct line*));
	}

	memcpy(&con->lines[con->margin_top + (max - num)],
	       cache, num * sizeof(struct line*));
}
Example #7
0
fractal_line_struct *fractal_polyline_new ( gint steps,
	gint random_x, gint random_y,
	gint width, gint random_w,
	gint seed, gdouble distribution,
	gboolean if_cracks, gint cracks_depth, gint cracks_width,
	gint cracks_branching_steps )
{
	fractal_line_struct *f;
	f = (fractal_line_struct *) x_malloc(sizeof(fractal_line_struct), "fractal_line_struct");
	f->steps = steps;
	f->random_x = random_x;
	f->random_y = random_y;
	f->seed = seed;
	f->distribution = distribution;
	f->width = width;
	f->random_w = random_w;
	f->if_cracks = if_cracks;
	f->cracks_depth = cracks_depth;
	f->cracks_width = cracks_width;
	f->cracks_branching_steps = cracks_branching_steps;
	f->polyline =  line_new ((gint) pow(2.0,(gdouble) f->steps),width);
	return f;
}
Example #8
0
/* not very efficient but simple */
Line *
io_readline (FILE *f)
{
  Line *l;
  int c;

  l = line_new();

  while (!feof(f))
  {
    c = fgetc(f);

    if (c == EOF || c == '\n')
      break;

    if (l->size >= l->max_size)
      line_grow(l);

    l->buf[l->size++] = c;
  }

  if (!l->size && feof(f))
  {
    line_free(l);
    return NULL;
  }

  if (l->size)
    line_compact(l);
  else
  {
    free(l->buf);
    l->buf = NULL;
  }

  return l;
}
Example #9
0
SHL_EXPORT
int tsm_screen_resize(struct tsm_screen *con, unsigned int x,
		      unsigned int y)
{
	struct line **cache;
	unsigned int i, j, width, diff, start;
	int ret;
	bool *tab_ruler;

	if (!con || !x || !y)
		return -EINVAL;

	if (con->size_x == x && con->size_y == y)
		return 0;

	/* First make sure the line buffer is big enough for our new screen.
	 * That is, allocate all new lines and make sure each line has enough
	 * cells to hold the new screen or the current screen. If we fail, we
	 * can safely return -ENOMEM and the buffer is still valid. We must
	 * allocate the new lines to at least the same size as the current
	 * lines. Otherwise, if this function fails in later turns, we will have
	 * invalid lines in the buffer. */
	if (y > con->line_num) {
		/* resize main buffer */
		cache = realloc(con->main_lines, sizeof(struct line*) * y);
		if (!cache)
			return -ENOMEM;

		if (con->lines == con->main_lines)
			con->lines = cache;
		con->main_lines = cache;

		/* resize alt buffer */
		cache = realloc(con->alt_lines, sizeof(struct line*) * y);
		if (!cache)
			return -ENOMEM;

		if (con->lines == con->alt_lines)
			con->lines = cache;
		con->alt_lines = cache;

		/* allocate new lines */
		if (x > con->size_x)
			width = x;
		else
			width = con->size_x;

		while (con->line_num < y) {
			ret = line_new(con, &con->main_lines[con->line_num],
				       width);
			if (ret)
				return ret;

			ret = line_new(con, &con->alt_lines[con->line_num],
				       width);
			if (ret) {
				line_free(con->main_lines[con->line_num]);
				return ret;
			}

			++con->line_num;
		}
	}

	/* Resize all lines in the buffer if we increase screen width. This
	 * will guarantee that all lines are big enough so we can resize the
	 * buffer without reallocating them later. */
	if (x > con->size_x) {
		tab_ruler = realloc(con->tab_ruler, sizeof(bool) * x);
		if (!tab_ruler)
			return -ENOMEM;
		con->tab_ruler = tab_ruler;

		for (i = 0; i < con->line_num; ++i) {
			ret = line_resize(con, con->main_lines[i], x);
			if (ret)
				return ret;

			ret = line_resize(con, con->alt_lines[i], x);
			if (ret)
				return ret;
		}
	}

	screen_inc_age(con);

	/* clear expansion/padding area */
	start = x;
	if (x > con->size_x)
		start = con->size_x;
	for (j = 0; j < con->line_num; ++j) {
		/* main-lines may go into SB, so clear all cells */
		i = 0;
		if (j < con->size_y)
			i = start;

		for ( ; i < con->main_lines[j]->size; ++i)
			screen_cell_init(con, &con->main_lines[j]->cells[i]);

		/* alt-lines never go into SB, only clear visible cells */
		i = 0;
		if (j < con->size_y)
			i = con->size_x;

		for ( ; i < x; ++i)
			screen_cell_init(con, &con->alt_lines[j]->cells[i]);
	}

	/* xterm destroys margins on resize, so do we */
	con->margin_top = 0;
	con->margin_bottom = con->size_y - 1;

	/* reset tabs */
	for (i = 0; i < x; ++i) {
		if (i % 8 == 0)
			con->tab_ruler[i] = true;
		else
			con->tab_ruler[i] = false;
	}

	/* We need to adjust x-size first as screen_scroll_up() and friends may
	 * have to reallocate lines. The y-size is adjusted after them to avoid
	 * missing lines when shrinking y-size.
	 * We need to carefully look for the functions that we call here as they
	 * have stronger invariants as when called normally. */

	con->size_x = x;
	if (con->cursor_x >= con->size_x)
		move_cursor(con, con->size_x - 1, con->cursor_y);

	/* scroll buffer if screen height shrinks */
	if (y < con->size_y) {
		diff = con->size_y - y;
		screen_scroll_up(con, diff);
		if (con->cursor_y > diff)
			move_cursor(con, con->cursor_x, con->cursor_y - diff);
		else
			move_cursor(con, con->cursor_x, 0);
	}

	con->size_y = y;
	con->margin_bottom = con->size_y - 1;
	if (con->cursor_y >= con->size_y)
		move_cursor(con, con->cursor_x, con->size_y - 1);

	return 0;
}
Example #10
0
static void screen_scroll_up(struct tsm_screen *con, unsigned int num)
{
	unsigned int i, j, max, pos;
	int ret;

	if (!num)
		return;

	/* TODO: more sophisticated ageing */
	con->age = con->age_cnt;

	max = con->margin_bottom + 1 - con->margin_top;
	if (num > max)
		num = max;

	/* We cache lines on the stack to speed up the scrolling. However, if
	 * num is too big we might get overflows here so use recursion if num
	 * exceeds a hard-coded limit.
	 * 128 seems to be a sane limit that should never be reached but should
	 * also be small enough so we do not get stack overflows. */
	if (num > 128) {
		screen_scroll_up(con, 128);
		return screen_scroll_up(con, num - 128);
	}
	struct line *cache[num];

	for (i = 0; i < num; ++i) {
		pos = con->margin_top + i;
		if (!(con->flags & TSM_SCREEN_ALTERNATE))
			ret = line_new(con, &cache[i], con->size_x);
		else
			ret = -EAGAIN;

		if (!ret) {
			link_to_scrollback(con, con->lines[pos]);
		} else {
			cache[i] = con->lines[pos];
			for (j = 0; j < con->size_x; ++j)
				screen_cell_init(con, &cache[i]->cells[j]);
		}
	}

	if (num < max) {
		memmove(&con->lines[con->margin_top],
			&con->lines[con->margin_top + num],
			(max - num) * sizeof(struct line*));
	}

	memcpy(&con->lines[con->margin_top + (max - num)],
	       cache, num * sizeof(struct line*));

	if (con->sel_active) {
		if (!con->sel_start.line && con->sel_start.y >= 0) {
			con->sel_start.y -= num;
			if (con->sel_start.y < 0) {
				con->sel_start.line = con->sb_last;
				while (con->sel_start.line && ++con->sel_start.y < 0)
					con->sel_start.line = con->sel_start.line->prev;
				con->sel_start.y = SELECTION_TOP;
			}
		}
		if (!con->sel_end.line && con->sel_end.y >= 0) {
			con->sel_end.y -= num;
			if (con->sel_end.y < 0) {
				con->sel_end.line = con->sb_last;
				while (con->sel_end.line && ++con->sel_end.y < 0)
					con->sel_end.line = con->sel_end.line->prev;
				con->sel_end.y = SELECTION_TOP;
			}
		}
	}
}
Example #11
0
int tsm_screen_resize(struct tsm_screen *con, unsigned int x,
			  unsigned int y)
{
	struct line **cache;
	unsigned int i, j, width, diff;
	int ret;
	bool *tab_ruler;

	if (!con || !x || !y)
		return -EINVAL;

	if (con->size_x == x && con->size_y == y)
		return 0;

	/* First make sure the line buffer is big enough for our new screen.
	 * That is, allocate all new lines and make sure each line has enough
	 * cells to hold the new screen or the current screen. If we fail, we
	 * can safely return -ENOMEM and the buffer is still valid. We must
	 * allocate the new lines to at least the same size as the current
	 * lines. Otherwise, if this function fails in later turns, we will have
	 * invalid lines in the buffer. */
	if (y > con->line_num) {
		cache = realloc(con->lines, sizeof(struct line*) * y);
		if (!cache)
			return -ENOMEM;

		con->lines = cache;
		if (x > con->size_x)
			width = x;
		else
			width = con->size_x;

		while (con->line_num < y) {
			ret = line_new(con, &cache[con->line_num], width);
			if (ret)
				return ret;
			++con->line_num;
		}
	}

	/* Resize all lines in the buffer if we increase screen width. This
	 * will guarantee that all lines are big enough so we can resize the
	 * buffer without reallocating them later. */
	if (x > con->size_x) {
		tab_ruler = realloc(con->tab_ruler, sizeof(bool) * x);
		if (!tab_ruler)
			return -ENOMEM;
		con->tab_ruler = tab_ruler;

		for (i = 0; i < con->line_num; ++i) {
			ret = line_resize(con, con->lines[i], x);
			if (ret)
				return ret;
		}
	}

	/* When resizing, we need to reset all the new cells, otherwise, the old
	 * data that was written there will reoccur on the screen.
	 * TODO: we overwrite way to much here; most of it should already be
	 * cleaned. Maybe it does more sense cleaning when _allocating_ or when
	 * _shrinking_, then we never clean twice (for performance reasons). */
	for (j = 0; j < con->line_num; ++j) {
		if (j >= con->size_y)
			i = 0;
		else
			i = con->size_x;
		if (x < con->lines[j]->size)
			width = x;
		else
			width = con->lines[j]->size;
		for (; i < width; ++i)
			cell_init(con, &con->lines[j]->cells[i]);
	}

	/* xterm destroys margins on resize, so do we */
	con->margin_top = 0;
	con->margin_bottom = con->size_y - 1;

	/* reset tabs */
	for (i = 0; i < x; ++i) {
		if (i % 8 == 0)
			con->tab_ruler[i] = true;
		else
			con->tab_ruler[i] = false;
	}

	/* We need to adjust x-size first as screen_scroll_up() and friends may
	 * have to reallocate lines. The y-size is adjusted after them to avoid
	 * missing lines when shrinking y-size.
	 * We need to carefully look for the functions that we call here as they
	 * have stronger invariants as when called normally. */

	con->size_x = x;
	if (con->cursor_x >= con->size_x)
		con->cursor_x = con->size_x - 1;

	/* scroll buffer if screen height shrinks */
	if (con->size_y != 0 && y < con->size_y) {
		diff = con->size_y - y;
		screen_scroll_up(con, diff);
		if (con->cursor_y > diff)
			con->cursor_y -= diff;
		else
			con->cursor_y = 0;
	}

	con->size_y = y;
	con->margin_bottom = con->size_y - 1;
	if (con->cursor_y >= con->size_y)
		con->cursor_y = con->size_y - 1;

	return 0;
}
Example #12
0
/* 
 * Minimum Width
 * The minimum width is the distance between the closest parallel lines
 * between which all of the point are placed.
 * To find the minimal width,
 * we'll go through a sequence of pairs of parallel lines the hold all of the points between them.
 * In each pair, one of the lines must coincide with a polygon edge.
 * The other line will be the most distant line that still touches the polygon
 * (There are at most n pairs). 
 * 1. For each pair, we'll find the distance between the two lines,
 *    and the width is the minimal distance.
 * 2. We'll find the pairs in the following way:
 * 3. The first pair will consist of two vertical lines that
 *    go thru the most left and the most right points.
 * 4. Then, for each pair, (exactly like in the diameter)
 *    we rotate the two parallel lines in the angle that
 *    move one line to lie on a new edge. 
 */
real_t convexhull_compute_min_width(line_t *width, polygon_t *chull)
{
  int i;
  real_t *ang, dist, value, rotate;
  real_t da, db, alpha, beta, xmin, xmax;
  dlink_t *ax, *ax_next;
  dlink_t *bx, *bx_next;
  dlink_t *x, *lx, *rx;
  point_t *a, *b, *p, *q;
  line_t *line;

  assert(width);
  assert(chull);
  assert(polygon_get_count(chull) >= 3);

  ang = (real_t *)malloc(polygon_get_count(chull) * sizeof(real_t));
  assert(ang);

  // Find the angle between verteces
  i = 0;
  ax = chull->head->prev;
  bx = chull->tail->next;
  do {
    a = (point_t *)ax->object;
    b = (point_t *)bx->object;

    ang[i] = arctan2r(point_get_y(b) - point_get_y(a),
		      point_get_x(b) - point_get_x(a));
    ang[i] = ang[i] > M_PI ? ang[i] - M_PI : ang[i];

    ax->spare = (void *)&ang[i];
    printf("(%lf,%lf) -> (%lf,%lf) < %lf deg\n",
	   point_get_x(a), point_get_y(a),
	   point_get_x(b), point_get_y(b),
	   ang[i] * 180 / M_PI);

    i++;
    ax = bx;
    bx = bx->next;
  } while (bx != chull->head);
  printf("Initialized the angle between verteces\n");

  // Find the most left and right point
  lx = NULL;
  rx = NULL;
  for (x = chull->tail->next; x != chull->head; x = x->next) {
    p = (point_t *)x->object;
    if (lx == NULL || point_get_x(p) < xmin) {
      lx = x;
      xmin = point_get_x(p);
    }
    if (rx == NULL || point_get_x(p) > xmax) {
      rx = x;
      xmax = point_get_x(p);
    }
  }
  printf("Founded the leftmost and rightmost points\n");

  ax = lx;
  bx = rx;
  dist = 0.0;
  p = NULL;
  q = NULL;
  rotate = M_PI_2; // pi / 2;
  line = line_new();

  do {
    a = (point_t *)ax->object;
    b = (point_t *)bx->object;
    printf("(%lf,%lf) -> (%lf,%lf)\n",
	   point_get_x(a), point_get_y(a),
	   point_get_x(b), point_get_y(b));

    value = get_distance_of_p2p(a, b);
    if (p == NULL || q == NULL || value < dist) {
      p = a;
      q = b;
      dist = value;
    }

    alpha = *((real_t *)ax->spare);
    beta = *((real_t *)bx->spare);

    printf("rotate: %lf, alpha: %lf, beta: %lf\n",
	   rotate * 180 / M_PI, alpha * 180 / M_PI, beta * 180 / M_PI);
    /*
    circle(((point_t *)a->object)->x, ((point_t *)a->object)->y, 10, 255, 0, 0);
    circle(((point_t *)b->object)->x, ((point_t *)b->object)->y, 10, 255, 0, 0);
    keyhit();
    circle(((point_t *)a->object)->x, ((point_t *)a->object)->y, 10, 0, 0, 0);
    circle(((point_t *)b->object)->x, ((point_t *)b->object)->y, 10, 0, 0, 0);
    */

    // Make alpha and beta in the range of acute angle
    if (alpha >= rotate) da = alpha - rotate;
    else da = M_PI + alpha - rotate;

    if (beta >= rotate) db = beta - rotate;
    else db = M_PI + beta - rotate;

    if (da < db) {
      rotate = alpha;
      if (ax->next == chull->head) ax_next = chull->tail->next;
      else ax_next -= ax->next;

      line_set_endpoints(line, a, (point_t *)ax_next->object);

      value = distance_from_point_to_line(b, line);
      if (p == NULL || q == NULL || value < dist) {
	p = a;
	q = b;
	dist = value;
      }
      line_clear(line);
      ax = ax_next;
    } else {
      rotate = beta;
      if (bx->next == chull->head) bx_next = chull->tail->next;
      else bx_next = bx->next;
      
      line_set_endpoints(line, b, (point_t *)bx_next->object);
      
      value = distance_from_point_to_line(a, line);
      if (p == NULL || q == NULL || value < dist) {
	p = b;
	q = a;
	dist = value;
      }
      line_clear(line);
      bx = bx_next;
    }
  } while (!((ax == rx && bx == lx) || (bx == rx && ax == lx)));

  for (x = chull->tail->next; x != chull->head; x = x->next)
    x->spare = NULL;

  line_set_endpoints(width, p, q);
  //line_assign(width, p, q);

  free(ang);

  return dist;
}