group farbfeld code in the single farbfeld tool around - 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
 (DIR) LICENSE
       ---
 (DIR) commit b525323a1383dfb008a8941753702e2b05d14eee
 (DIR) parent f5bdc6b7ddfd050efc31f5cc89a6fba87e58819f
 (HTM) 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)
        {