URI: 
       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 }