group farbfeld code in the single farbfeld tool around - ploot - simple plotting tools HTML git clone git://bitreich.org/ploot git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ploot DIR Log DIR Files DIR Refs DIR Tags DIR README DIR LICENSE --- DIR commit b525323a1383dfb008a8941753702e2b05d14eee DIR parent f5bdc6b7ddfd050efc31f5cc89a6fba87e58819f HTML Author: Josuah Demangeon <me@josuah.net> Date: Wed, 23 Jun 2021 23:39:40 +0200 group farbfeld code in the single farbfeld tool around Diffstat: M Makefile | 4 ++-- D ffplot.c | 148 ------------------------------- D ffplot.h | 34 ------------------------------- M ploot-farbfeld.c | 166 +++++++++++++++++++++++++++++-- 4 files changed, 159 insertions(+), 193 deletions(-) --- DIR diff --git a/Makefile b/Makefile @@ -7,8 +7,8 @@ LFLAGS = -static -lm PREFIX = /usr/local MANOREFIX = $(PREFIX)/share/man -SRC = csv.c drawille.c ffplot.c font.c font13.c font8.c scale.c util.c -INC = csv.h drawille.h ffplot.h font.h scale.h util.h +SRC = csv.c drawille.c font.c font13.c font8.c scale.c util.c +INC = csv.h drawille.h font.h scale.h util.h BIN = ploot-farbfeld ploot-feed ploot-braille ploot-text OBJ = ${SRC:.c=.o} DIR diff --git a/ffplot.c b/ffplot.c @@ -1,148 +0,0 @@ -#include "ffplot.h" - -#include <arpa/inet.h> -#include <stddef.h> -#include <string.h> -#include <stdio.h> -#include <stdint.h> - -#include "font.h" -#include "util.h" - -/* - * Convert (x,y) coordinates to (row,col) for printing into the buffer. - * The buffer only contain one number, so the coordinate is a single integer: - * width * y + y. - * The coordinates are shifted by offx and offy to permit relative coordinates. - * - * The convention used: y - * - (0,0) is at the lower left corner of the plotvas. | - * - (0,1) is above it. +--x - */ -void -ffplot_pixel(struct ffplot *plot, struct ffcolor *color, - int x, int y) -{ - x += plot->x; - y += plot->y; - if (x < 0 || x >= plot->w || y < 0 || y >= plot->h) - return; - memcpy(plot->buf + plot->w * (plot->h - 1 - y) + x, color, sizeof(*plot->buf)); -} - -void -ffplot_rectangle(struct ffplot *plot, struct ffcolor *color, - int y1, int x1, - int y2, int x2) -{ - int x, y, ymin, xmin, ymax, xmax; - - ymin = MIN(y1, y2); ymax = MAX(y1, y2); - xmin = MIN(x1, x2); xmax = MAX(x1, x2); - - for (y = ymin; y <= ymax; y++) - for (x = xmin; x <= xmax; x++) - ffplot_pixel(plot, color, x, y); -} - -/* - * From Bresenham's line algorithm and dcat's tplot. - */ -void -ffplot_line(struct ffplot *plot, struct ffcolor *color, - int x0, int y0, - int x1, int y1) -{ - int dy, dx, sy, sx, err, e; - - sx = x0 < x1 ? 1 : -1; - sy = y0 < y1 ? 1 : -1; - dx = ABS(x1 - x0); - dy = ABS(y1 - y0); - err = (dy > dx ? dy : -dx) / 2; - - for (;;) { - ffplot_pixel(plot, color, x0, y0); - - if (y0 == y1 && x0 == x1) - break; - - e = err; - if (e > -dy) { - y0 += sy; - err -= dx; - } - if (e < dx) { - x0 += sx; - err += dy; - } - } -} - -/* - * Draw a coloured glyph from font f centered on y. - */ -int -ffplot_char(struct ffplot *plot, struct ffcolor *color, struct font *ft, char c, - int x, int y) -{ - int yf, xf, wf; - - if (c & 0x80) - c = '\0'; - y -= ft->height / 2; - wf = font_width(ft, c); - for (xf = 0; xf < wf; xf++) - for (yf = 0; yf < ft->height; yf++) - if (ft->glyph[(int)c][wf * (ft->height - yf) + xf] == 3) - ffplot_pixel(plot, color, x + xf, y + yf); - return wf + 1; -} - -/* - * Draw a left aligned string without wrapping it. - */ -size_t -ffplot_text_left(struct ffplot *plot, struct ffcolor *color, struct font *ft, - char *s, int x, int y) -{ - for (; *s != '\0'; s++) - x += ffplot_char(plot, color, ft, *s, x, y); - return x; -} - -/* - * Draw a center aligned string without wrapping it. - */ -size_t -ffplot_text_center(struct ffplot *plot, struct ffcolor *color, struct font *ft, - char *s, int x, int y) -{ - x -= font_strlen(ft, s) / 2; - return ffplot_text_left(plot, color, ft, s, x, y); -} - -/* - * Draw a right aligned string without wrapping it. - */ -size_t -ffplot_text_right(struct ffplot *plot, struct ffcolor *color, struct font *ft, - char *s, int x, int y) -{ - x -= font_strlen(ft, s); - return ffplot_text_left(plot, color, ft, s, x, y); -} - -void -ffplot_print(FILE *fp, struct ffplot *plot) -{ - uint32_t w, h; - - w = htonl(plot->w); - h = htonl(plot->h); - - fprintf(stdout, "ffplot"); - fwrite(&w, sizeof(w), 1, fp); - fwrite(&h, sizeof(h), 1, fp); - fwrite(plot->buf, plot->w * plot->h, sizeof(*plot->buf), fp); -} DIR diff --git a/ffplot.h b/ffplot.h @@ -1,34 +0,0 @@ -#ifndef FFPLOT_H -#define FFPLOT_H - -#include <stdio.h> -#include <stddef.h> -#include <stdint.h> - -#include "font.h" - -struct ffcolor { - uint16_t red; - uint16_t green; - uint16_t blue; - uint16_t alpha; -}; - -struct ffplot { - int w; /* width */ - int h; /* height */ - int x; /* x offset */ - int y; /* y offset */ - struct ffcolor *buf; -}; - -void ffplot_pixel(struct ffplot *, struct ffcolor *, int, int); -void ffplot_rectangle(struct ffplot *, struct ffcolor *, int, int, int, int); -void ffplot_line(struct ffplot *, struct ffcolor *, int, int, int, int); -int ffplot_char(struct ffplot *, struct ffcolor *, struct font *, char, int, int); -size_t ffplot_text_left(struct ffplot *, struct ffcolor *, struct font *, char *, int, int); -size_t ffplot_text_center(struct ffplot *, struct ffcolor *, struct font *, char *, int, int); -size_t ffplot_text_right(struct ffplot *, struct ffcolor *, struct font *, char *, int, int); -void ffplot_print(FILE *, struct ffplot *); - -#endif DIR diff --git a/ploot-farbfeld.c b/ploot-farbfeld.c @@ -4,6 +4,7 @@ #include <fcntl.h> #include <limits.h> #include <math.h> +#include <stddef.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -11,10 +12,9 @@ #include <time.h> #include <unistd.h> #include "csv.h" -#include "ffplot.h" #include "font.h" -#include "util.h" #include "scale.h" +#include "util.h" #ifndef __OpenBSD__ #define pledge(...) 0 @@ -50,16 +50,22 @@ #define LEGEND_W (100) #define LEGEND_H (PLOT_H) -struct colorname { - char *name; - struct ffcolor color; +struct ffcolor { + uint16_t red; + uint16_t green; + uint16_t blue; + uint16_t alpha; }; -static char *tflag = ""; -static char *uflag = ""; -static struct font *font = &font13; +struct ffplot { + int w, h, x, y; /* width, height and coordinamtes */ + struct ffcolor *buf; +}; -static struct colorname colorname[] = { +static struct colorname { + char *name; + struct ffcolor color; +} colorname[] = { /* name red green blue alpha */ { "red", { 0xffff, 0x4444, 0x4444, 0xffff } }, { "orange", { 0xffff, 0x9999, 0x4444, 0xffff } }, @@ -70,6 +76,148 @@ static struct colorname colorname[] = { { NULL, { 0, 0, 0, 0 } } }; +static char *tflag = ""; +static char *uflag = ""; +static struct font *font = &font13; + +/* + * Convert (x,y) coordinates to (row,col) for printing into the buffer. + * The buffer only contain one number, so the coordinate is a single integer: + * width * y + y. + * The coordinates are shifted by offx and offy to permit relative coordinates. + * + * The convention used: y + * - (0,0) is at the lower left corner of the plotvas. | + * - (0,1) is above it. +--x + */ +static void +ffplot_pixel(struct ffplot *plot, struct ffcolor *color, + int x, int y) +{ + x += plot->x; + y += plot->y; + if (x < 0 || x >= plot->w || y < 0 || y >= plot->h) + return; + memcpy(plot->buf + plot->w * (plot->h - 1 - y) + x, color, sizeof(*plot->buf)); +} + +static void +ffplot_rectangle(struct ffplot *plot, struct ffcolor *color, + int y1, int x1, + int y2, int x2) +{ + int x, y, ymin, xmin, ymax, xmax; + + ymin = MIN(y1, y2); ymax = MAX(y1, y2); + xmin = MIN(x1, x2); xmax = MAX(x1, x2); + + for (y = ymin; y <= ymax; y++) + for (x = xmin; x <= xmax; x++) + ffplot_pixel(plot, color, x, y); +} + +/* + * From Bresenham's line algorithm and dcat's tplot. + */ +static void +ffplot_line(struct ffplot *plot, struct ffcolor *color, + int x0, int y0, + int x1, int y1) +{ + int dy, dx, sy, sx, err, e; + + sx = x0 < x1 ? 1 : -1; + sy = y0 < y1 ? 1 : -1; + dx = ABS(x1 - x0); + dy = ABS(y1 - y0); + err = (dy > dx ? dy : -dx) / 2; + + for (;;) { + ffplot_pixel(plot, color, x0, y0); + + if (y0 == y1 && x0 == x1) + break; + + e = err; + if (e > -dy) { + y0 += sy; + err -= dx; + } + if (e < dx) { + x0 += sx; + err += dy; + } + } +} + +/* + * Draw a coloured glyph from font f centered on y. + */ +static int +ffplot_char(struct ffplot *plot, struct ffcolor *color, struct font *ft, char c, + int x, int y) +{ + int yf, xf, wf; + + if (c & 0x80) + c = '\0'; + y -= ft->height / 2; + wf = font_width(ft, c); + for (xf = 0; xf < wf; xf++) + for (yf = 0; yf < ft->height; yf++) + if (ft->glyph[(int)c][wf * (ft->height - yf) + xf] == 3) + ffplot_pixel(plot, color, x + xf, y + yf); + return wf + 1; +} + +/* + * Draw a left aligned string without wrapping it. + */ +static size_t +ffplot_text_left(struct ffplot *plot, struct ffcolor *color, struct font *ft, + char *s, int x, int y) +{ + for (; *s != '\0'; s++) + x += ffplot_char(plot, color, ft, *s, x, y); + return x; +} + +/* + * Draw a center aligned string without wrapping it. + */ +static size_t +ffplot_text_center(struct ffplot *plot, struct ffcolor *color, struct font *ft, + char *s, int x, int y) +{ + x -= font_strlen(ft, s) / 2; + return ffplot_text_left(plot, color, ft, s, x, y); +} + +/* + * Draw a right aligned string without wrapping it. + */ +static size_t +ffplot_text_right(struct ffplot *plot, struct ffcolor *color, struct font *ft, + char *s, int x, int y) +{ + x -= font_strlen(ft, s); + return ffplot_text_left(plot, color, ft, s, x, y); +} + +static void +ffplot_print(FILE *fp, struct ffplot *plot) +{ + uint32_t w, h; + + w = htonl(plot->w); + h = htonl(plot->h); + + fprintf(stdout, "ffplot"); + fwrite(&w, sizeof(w), 1, fp); + fwrite(&h, sizeof(h), 1, fp); + fwrite(plot->buf, plot->w * plot->h, sizeof(*plot->buf), fp); +} + static int ffplot_t2x(time_t t, time_t tmin, time_t tmax) {