static void walk(Chaincode *cc, int start_node, unsigned char **pixels, int dx, int dy)
{
    int x, y;
    int allocated = 20;
    int count = 0;
    Rope *rope;
    char *steps;
    
    assert(0 <= start_node  &&  start_node < cc->node_count);
    
    x = cc->nodes[start_node].x;
    y = cc->nodes[start_node].y;
    
    /* Check that there's indeed a road in the given direction. */
    if (!pixels[y + dy][x + dx])
        return;

    /* Check that we haven't passed here before. */
    if (passed_edge(pixels[y][x], dx, dy))
        return;

    cc->nodes[start_node].rope_indices[count_passed_edges(pixels[y][x])] = cc->rope_count;

    steps = MALLOC(char, allocated);
    mark_edge(pixels, x, y, dx, dy);

    x += dx;
    y += dy;
    *append_step(&steps, &count, &allocated) = chaincode_char(dx, dy);
    if (pixels[y][x] == 1)
    {
        pixels[y][x] = 0;
        determine_direction_first_time(pixels, x, y, &dx, &dy);
        
        while (1)
        {
            x += dx;
            y += dy;
            *append_step(&steps, &count, &allocated) = chaincode_char(dx, dy);
            if (pixels[y][x] != 1)  break;
            pixels[y][x] = 0;

            determine_direction(pixels, x, y, &dx, &dy);
        }
    }

    /* We've arrived at a hot point. Mark the entrance. */
    assert(!passed_edge(pixels[y][x], -dx, -dy));
    mark_edge(pixels, x, y, -dx, -dy);
    
    /* Add the rope. */
    rope = chaincode_append_rope(cc);
    rope->start = start_node;
    rope->end = find_node(cc, x, y);
    rope->steps = REALLOC(char, steps, count);
    rope->length = count;
    cc->nodes[rope->end].rope_indices[count_passed_edges(pixels[y][x]) - 1] = cc->rope_count - 1;
}
Example #2
0
static pixel_outline_type
find_one_outline (edge_type original_edge,
		  unsigned original_row, unsigned original_col,
		  bitmap_type *marked)
{
  pixel_outline_type outline = new_pixel_outline ();
  unsigned row = original_row, col = original_col;
  edge_type edge = original_edge;

  do
    {
      /* Put this edge on to the output list, changing to Cartesian, and
         taking account of the side bearings.  */
      append_coordinate (&outline, col,
                         sel_get_height() - row, edge);

      mark_edge (edge, row, col, marked);
      next_outline_edge (&edge, &row, &col);
    }
  while (row != original_row || col != original_col || edge != original_edge);

  return outline;
}