tffplot.c - ploot - simple plotting tools HTML git clone git://bitreich.org/ploot git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ploot DIR Log DIR Files DIR Refs DIR 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 }