aboutsummaryrefslogtreecommitdiffstats
path: root/demo.c
diff options
context:
space:
mode:
Diffstat (limited to 'demo.c')
-rw-r--r--demo.c198
1 files changed, 198 insertions, 0 deletions
diff --git a/demo.c b/demo.c
new file mode 100644
index 0000000..168c9e4
--- /dev/null
+++ b/demo.c
@@ -0,0 +1,198 @@
+/* See LICENSE file for copyright and license details. */
+#include "libtracebitmap.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define MIN(A, B) ((A) < (B) ? (A) : (B))
+#define MAX(A, B) ((A) > (B) ? (A) : (B))
+
+
+struct data {
+ size_t height;
+ size_t width;
+ size_t y;
+ size_t x;
+ int beginning;
+ const char ***plot;
+};
+
+
+static int
+new_component(int negative, void *user_data)
+{
+ struct data *data = user_data;
+ data->beginning = 1;
+ printf("%s", negative ? "-" : "+");
+ fflush(stdout);
+ return 0;
+}
+
+static const char *
+mix(const char *a, const char *b)
+{
+ static const struct {
+ const char *text;
+ uint16_t bits;
+ } symbols[] = {
+ {" ", 0x0000}, {"┼", 0x1111},
+ {"╵", 0x1000}, {"┬", 0x0111},
+ {"╶", 0x0100}, {"┤", 0x1011},
+ {"╷", 0x0010}, {"┴", 0x1101},
+ {"╴", 0x0001}, {"├", 0x1110},
+ {"│", 0x1010}, {"─", 0x0101},
+ {"└", 0x1100}, {"┐", 0x0011},
+ {"┘", 0x1001}, {"┌", 0x0110}
+ };
+ uint16_t bits;
+ size_t i, j;
+ for (i = 0; strcmp(a, symbols[i].text); i++);
+ for (j = 0; strcmp(b, symbols[j].text); j++);
+ bits = symbols[i].bits | symbols[j].bits;
+ for (i = 0; bits != symbols[i].bits; i++);
+ return symbols[i].text;
+}
+
+static int
+new_stop(size_t y, size_t x, void *user_data)
+{
+ struct data *data = user_data;
+ size_t y0, y1, y2;
+ size_t x0, x1, x2;
+ printf(" (%zu,%zu)", y, x);
+ fflush(stdout);
+ if (data->beginning) {
+ data->beginning = 0;
+ data->y = y;
+ data->x = x;
+ } else {
+ y0 = MIN(data->y, y);
+ x0 = MIN(data->x, x);
+ y2 = MAX(data->y, y);
+ x2 = MAX(data->x, x);
+ if (y0 == y2) {
+ y1 = y0;
+ for (x1 = x0; x1 < x2; x1++) {
+ data->plot[y1 * 2][x1 * 2 + 0] = mix(data->plot[y1 * 2][x1 * 2 + 0], "╶");
+ data->plot[y1 * 2][x1 * 2 + 1] = mix(data->plot[y1 * 2][x1 * 2 + 1], "─");
+ data->plot[y1 * 2][x1 * 2 + 2] = mix(data->plot[y1 * 2][x1 * 2 + 2], "╴");
+ }
+ } else {
+ x1 = x0;
+ for (y1 = y0; y1 < y2; y1++) {
+ data->plot[y1 * 2 + 0][x1 * 2] = mix(data->plot[y1 * 2 + 0][x1 * 2], "╷");
+ data->plot[y1 * 2 + 1][x1 * 2] = mix(data->plot[y1 * 2 + 1][x1 * 2], "│");
+ data->plot[y1 * 2 + 2][x1 * 2] = mix(data->plot[y1 * 2 + 2][x1 * 2], "╵");
+ }
+ }
+ data->y = y;
+ data->x = x;
+ }
+ return 0;
+}
+
+
+static int
+component_finished(void *user_data)
+{
+ (void) user_data;
+ printf("\n");
+ fflush(stdout);
+ return 0;
+}
+
+
+int
+main(void)
+{
+ struct libtracebitmap_bitmap bitmap;
+ size_t size = 0;
+ size_t len = 0;
+ ssize_t rd;
+ size_t width, i, j;
+ size_t y, x;
+ int r;
+ const char ***plot;
+ struct data data;
+
+ bitmap.image = NULL;
+ for (;;) {
+ if (len == size) {
+ size += 1024;
+ bitmap.image = realloc(bitmap.image, size);
+ if (!bitmap.image) {
+ perror("realloc");
+ exit(1);
+ }
+ }
+ rd = read(STDIN_FILENO, &bitmap.image[len], size - len);
+ if (rd <= 0) {
+ if (!rd)
+ break;
+ perror("read");
+ exit(1);
+ }
+ len += (size_t)rd;
+ }
+
+ bitmap.height = 0;
+ bitmap.width = 0;
+ width = 0;
+ for (i = j = 0; j < len; j++) {
+ if ((char)bitmap.image[j] == '\n') {
+ if (!bitmap.height++) {
+ bitmap.width = width;
+ } else {
+ if (bitmap.width != width) {
+ fprintf(stderr, "Invalid input: each line must have the same length.\n");
+ exit(1);
+ }
+ }
+ width = 0;
+ } else if ((char)bitmap.image[j] == '.') {
+ bitmap.image[i++] = LIBTRACEBITMAP_INK_OFF;
+ width += 1;
+ } else if ((char)bitmap.image[j] == 'x') {
+ bitmap.image[i++] = LIBTRACEBITMAP_INK_ON;
+ width += 1;
+ } else {
+ fprintf(stderr, "Invalid input: may only contain '.', 'x', and <newline> characters.\n");
+ exit(1);
+ }
+ }
+ if (width) {
+ fprintf(stderr, "Invalid input: must end with <newline> character.\n");
+ exit(1);
+ }
+
+ plot = calloc(bitmap.height * 2 + 1, sizeof(*plot));
+ for (y = 0; y < bitmap.height * 2 + 1; y++) {
+ plot[y] = calloc(bitmap.width * 2 + 1, sizeof(**plot));
+ for (x = 0; x < bitmap.width * 2 + 1; x++)
+ plot[y][x] = " ";
+ }
+ for (y = 0, i = 0; y < bitmap.height; y++)
+ for (x = 0; x < bitmap.width; x++, i++)
+ plot[y * 2 + 1][x * 2 + 1] = (bitmap.image[i] == LIBTRACEBITMAP_INK_ON ? "x" : ".");
+
+ data.height = bitmap.height;
+ data.width = bitmap.width;
+ data.plot = plot;
+
+ r = libtracebitmap_trace(&bitmap, new_component, new_stop, component_finished, &data);
+ if (r)
+ exit(r);
+
+ for (y = 0; y < bitmap.height * 2 + 1; y++) {
+ for (x = 0; x < bitmap.width * 2 + 1; x++)
+ printf("%s", plot[y][x]);
+ printf("\n");
+ free(plot[y]);
+ }
+
+ free(plot);
+ free(bitmap.image);
+ return 0;
+}