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; }
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; }