Introduction
Introduction Statistics Contact Development Disclaimer Help
drawille.c - ploot - simple plotting tools
git clone git://bitreich.org/ploot git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65…
Log
Files
Refs
Tags
README
LICENSE
---
drawille.c (3796B)
---
1 #include "drawille.h"
2 #include <stdint.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <math.h>
7 #include "font.h"
8
9 /*
10 * Terminal-based plotting using drawille character, aka drawille.
11 */
12
13 /* parameters used to draw a line */
14 struct line {
15 int x0, y0, x1, y1; /* point of the line */
16 int dx, dy, sx, sy, err; /* parameters for the algorythm …
17 };
18
19 /*
20 * Turn on the bit at position (row, col) of a single cell. The
21 * pattern is not linear (1-4-2-5-3-6-7-8), because it matches the
22 * drawille pattern.
23 */
24 static void
25 drawille_cell_dot(uint8_t *cell, int row, int col)
26 {
27 uint8_t flags[4][2] = {
28 { 0x01, 0x08 },
29 { 0x02, 0x10 },
30 { 0x04, 0x20 },
31 { 0x40, 0x80 },
32 };
33
34 *cell |= flags[row][col];
35 }
36
37 static size_t
38 drawille_cell_utf(uint8_t cell, char *utf)
39 {
40 long rune;
41
42 rune = 10240 + cell;
43 utf[0] = (char)(0xe0 | (0x0f & (rune >> 12))); /* 1110xxx…
44 utf[1] = (char)(0x80 | (0x3f & (rune >> 6))); /* 10xxxxxx…
45 utf[2] = (char)(0x80 | (0x3f & (rune))); /* 10xxxxxx */
46 return 3;
47 }
48
49 static uint8_t
50 drawille_get(struct drawille *drw, int row, int col)
51 {
52 return drw->buf[row * drw->col + col];
53 }
54
55 size_t
56 drawille_put_row(FILE *fp, struct drawille *drw, int row)
57 {
58 char txt[] = "xxx";
59 size_t n;
60
61 n = 0;
62 for (int col = 0; col < drw->col; col++) {
63 drawille_cell_utf(drawille_get(drw, row, col), txt);
64 n += fputs(txt, fp);
65 }
66 return n;
67 }
68
69 /*
70 * Coordinates are passed as (x, y), but the canvas stores bits as
71 * (row, col). Conversion is made by this function.
72 */
73 void
74 drawille_dot(struct drawille *drw, int x, int y)
75 {
76 if (x < 0 || x / 2 >= drw->col || y < 0 || y / 4 >= drw->row)
77 return;
78 drawille_cell_dot(drw->buf + (drw->row - y / 4 - 1) * drw->col +…
79 3 - y % 4,
80 x % 2);
81 }
82
83 struct drawille *
84 drawille_new(int row, int col)
85 {
86 struct drawille *drw;
87
88 if ((drw = calloc(sizeof(struct drawille) + row * col, 1)) == NU…
89 return NULL;
90 drw->row = row;
91 drw->col = col;
92 return drw;
93 }
94
95 static void
96 drawille_line_init(struct line *l, int x0, int y0, int x1, int y1)
97 {
98 l->x0 = x0;
99 l->y0 = y0;
100 l->x1 = x1;
101 l->y1 = y1;
102 l->sx = x0 < x1 ? 1 : -1;
103 l->sy = y0 < y1 ? 1 : -1;
104 l->dx = abs(x1 - x0);
105 l->dy = abs(y1 - y0);
106 l->err = (l->dx > l->dy ? l->dx : -l->dy) / 2;
107 }
108
109 static int
110 drawille_line_next(struct line *l)
111 {
112 int err;
113
114 if (l->x0 == l->x1 && l->y0 == l->y1)
115 return 0;
116
117 err = l->err;
118 if (err > -l->dx) {
119 l->x0 += l->sx;
120 l->err -= l->dy;
121 }
122 if (err < l->dy) {
123 l->y0 += l->sy;
124 l->err += l->dx;
125 }
126 return 1;
127 }
128
129 void
130 drawille_line(struct drawille *drw, int x0, int y0, int x1, int y1)
131 {
132 struct line l;
133
134 drawille_line_init(&l, x0, y0, x1, y1);
135 do {
136 drawille_dot(drw, l.x0, l.y0);
137 } while (drawille_line_next(&l));
138 }
139
140 void
141 drawille_histogram_dot(struct drawille *drw, int x, int y, int zero)
142 {
143 int sign;
144
145 sign = (y > zero) ? (+1) : (-1);
146 for (; y != zero; y -= sign)
147 drawille_dot(drw, x, y);
148 drawille_dot(drw, x, y);
149 }
150
151 void
152 drawille_histogram_line(struct drawille *drw, int x0, int y0, int x1, in…
153 {
154 struct line l;
155
156 drawille_line_init(&l, x0, y0, x1, y1);
157 do {
158 drawille_histogram_dot(drw, l.x0, l.y0, zero);
159 } while (drawille_line_next(&l));
160 }
161
162 static int
163 drawille_text_glyph(struct drawille *drw, int x, int y, struct font *fon…
164 {
165 int w;
166 char *glyph;
167
168 glyph = font->glyph[(c > 127 || c < 0) ? 0 : c];
169 w = strlen(glyph) / font->height;
170 for (int ix = 0; ix < w; ix++)
171 for (int iy = 0; iy < font->height; iy++)
172 if (glyph[ix + (font->height - 1) * w - iy * w] …
173 drawille_dot(drw, x + ix, y + iy);
174 return w;
175 }
176
177 char *
178 drawille_text(struct drawille *drw, int x, int y, struct font *font, cha…
179 {
180 if (drw->row*4 < font->height)
181 return NULL;
182 for (; *s != '\0' && x < drw->col*2; s++, x++)
183 x += drawille_text_glyph(drw, x, y, font, *s);
184 return s;
185 }
You are viewing proxied material from bitreich.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.