|
|
tffplot.c - ploot - simple plotting tools |
|
|
 |
git clone git://bitreich.org/ploot git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ploot (git://bitreich.org) |
|
|
 |
Log |
|
|
 |
Files |
|
|
 |
Refs |
|
|
 |
Tags |
|
|
|
--- |
|
|
|
tffplot.c (3180B) |
|
|
|
--- |
|
|
|
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, "ffplot"); |
|
|
|
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 } |
|