tffplot.c - ploot - simple plotting tools
(HTM) git clone git://bitreich.org/ploot git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ploot
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Tags
(DIR) README
---
tffplot.c (3182B)
---
1 #include "ffplot.h"
2
3 #include <arpa/inet.h>
4 #include <stddef.h>
5 #include <string.h>
6 #include <stdio.h>
7 #include <stdint.h>
8
9 #include "font.h"
10 #include "util.h"
11
12 /*
13 * Convert (x,y) coordinates to (row,col) for printing into the buffer.
14 * The buffer only contain one number, so the coordinate is a single integer:
15 * width * y + y.
16 * The coordinates are shifted by offx and offy to permit relative coordinates.
17 *
18 * The convention used: y
19 * - (0,0) is at the lower left corner of the plotvas. |
20 * - (0,1) is above it. +--x
21 */
22 void
23 ffplot_pixel(struct ffplot *plot, struct ffcolor *color,
24 int x, int y)
25 {
26 x += plot->x;
27 y += plot->y;
28 if (x < 0 || x >= plot->w || y < 0 || y >= plot->h)
29 return;
30 memcpy(plot->buf + plot->w * (plot->h - 1 - y) + x, color, sizeof(*plot->buf));
31 }
32
33 void
34 ffplot_rectangle(struct ffplot *plot, struct ffcolor *color,
35 int y1, int x1,
36 int y2, int x2)
37 {
38 int x, y, ymin, xmin, ymax, xmax;
39
40 ymin = MIN(y1, y2); ymax = MAX(y1, y2);
41 xmin = MIN(x1, x2); xmax = MAX(x1, x2);
42
43 for (y = ymin; y <= ymax; y++)
44 for (x = xmin; x <= xmax; x++)
45 ffplot_pixel(plot, color, x, y);
46 }
47
48 /*
49 * From Bresenham's line algorithm and dcat's tplot.
50 */
51 void
52 ffplot_line(struct ffplot *plot, struct ffcolor *color,
53 int x0, int y0,
54 int x1, int y1)
55 {
56 int dy, dx, sy, sx, err, e;
57
58 sx = x0 < x1 ? 1 : -1;
59 sy = y0 < y1 ? 1 : -1;
60 dx = ABS(x1 - x0);
61 dy = ABS(y1 - y0);
62 err = (dy > dx ? dy : -dx) / 2;
63
64 for (;;) {
65 ffplot_pixel(plot, color, x0, y0);
66
67 if (y0 == y1 && x0 == x1)
68 break;
69
70 e = err;
71 if (e > -dy) {
72 y0 += sy;
73 err -= dx;
74 }
75 if (e < dx) {
76 x0 += sx;
77 err += dy;
78 }
79 }
80 }
81
82 /*
83 * Draw a coloured glyph from font f centered on y.
84 */
85 int
86 ffplot_char(struct ffplot *plot, struct ffcolor *color, struct font *ft, char c,
87 int x, int y)
88 {
89 int yf, xf, wf;
90
91 if (c & 0x80)
92 c = '\0';
93 y -= ft->height / 2;
94 wf = font_width(ft, c);
95 for (xf = 0; xf < wf; xf++)
96 for (yf = 0; yf < ft->height; yf++)
97 if (ft->glyph[(int)c][wf * (ft->height - yf) + xf] == 3)
98 ffplot_pixel(plot, color, x + xf, y + yf);
99 return wf + 1;
100 }
101
102 /*
103 * Draw a left aligned string without wrapping it.
104 */
105 size_t
106 ffplot_text_left(struct ffplot *plot, struct ffcolor *color, struct font *ft,
107 char *s, int x, int y)
108 {
109 for (; *s != '\0'; s++)
110 x += ffplot_char(plot, color, ft, *s, x, y);
111 return x;
112 }
113
114 /*
115 * Draw a center aligned string without wrapping it.
116 */
117 size_t
118 ffplot_text_center(struct ffplot *plot, struct ffcolor *color, struct font *ft,
119 char *s, int x, int y)
120 {
121 x -= font_strlen(ft, s) / 2;
122 return ffplot_text_left(plot, color, ft, s, x, y);
123 }
124
125 /*
126 * Draw a right aligned string without wrapping it.
127 */
128 size_t
129 ffplot_text_right(struct ffplot *plot, struct ffcolor *color, struct font *ft,
130 char *s, int x, int y)
131 {
132 x -= font_strlen(ft, s);
133 return ffplot_text_left(plot, color, ft, s, x, y);
134 }
135
136 void
137 ffplot_print(FILE *fp, struct ffplot *plot)
138 {
139 uint32_t w, h;
140
141 w = htonl(plot->w);
142 h = htonl(plot->h);
143
144 fprintf(stdout, "farbfeld");
145 fwrite(&w, sizeof(w), 1, fp);
146 fwrite(&h, sizeof(h), 1, fp);
147 fwrite(plot->buf, plot->w * plot->h, sizeof(*plot->buf), fp);
148 }