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