1#include "draw.h"
2
3static void draw_bitmap(uint32_t* dst, int w, int h, uint8_t* bmp,
4 int bw, int bh, int x, int y, uint32_t fg);
5static void blend(uint32_t* dst, int w, int h, int x, int y, uint8_t alpha,
6 uint32_t fg);
7
8/* draw bitmap of properties (look: vvvv) to screen */
9static void draw_bitmap(uint32_t* dst, int w, int h, uint8_t* bmp,
10 int bw, int bh, int x, int y, uint32_t fg)
11{
12 for (int by = 0; by < bh; by++) {
13 for (int bx = 0; bx < bw; bx++) {
14 uint8_t a = bmp[by * bw + bx];
15 blend(dst, w, h, x + bx, y + by, a, fg);
16 }
17 }
18}
19
20/* blend a pixel using alpha compositong */
21static void blend(uint32_t* dst, int w, int h, int x, int y, uint8_t alpha,
22 uint32_t fg)
23{
24 uint8_t* px;
25 uint8_t fg_r;
26 uint8_t fg_g;
27 uint8_t fg_b;
28
29 if (x < 0 || x >= w || y < 0 || y >= h || alpha == 0)
30 return; /* transparent/oob */
31
32 /* ptr to px at (x, y) */
33 px = (uint8_t*)&dst[y * w + x];
34
35 /* unpack fg colour*/
36 fg_r = (uint8_t)(fg & 0xff);
37 fg_g = (uint8_t)((fg >> 8) & 0xff);
38 fg_b = (uint8_t)((fg >> 16) & 0xff);
39
40 /* alpha blend each channel */
41 px[0] = (uint8_t)((fg_r * alpha + px[0] * (255 - alpha)) / 255);
42 px[1] = (uint8_t)((fg_g * alpha + px[1] * (255 - alpha)) / 255);
43 px[2] = (uint8_t)((fg_b * alpha + px[2] * (255 - alpha)) / 255);
44
45 px[3] = 255;
46}
47
48void draw_clear(uint32_t* dst, int w, int h, uint32_t col)
49{
50 for (int i = 0; i < w*h; i++)
51 dst[i] = col;
52}
53
54void draw_rune(uint32_t* dst, int w, int h, int cl, int rw, int cw, int ch,
55 uint32_t bg)
56{
57 int x0 = cl * cw; /* x origin of cell */
58 int y0 = rw * ch; /* y origin of cell */
59 int x;
60 int y;
61
62 /* iterate through columns */
63 for (y = y0; y < y0+ch && y < h; y++) {
64 if (y < 0)
65 continue;
66
67
68 /* through rows */
69 for (x = x0; x < x0+cw && x < w; x++) {
70 if (x < 0)
71 continue;
72 dst[y * w + x] = bg;
73 }
74 }
75}
76
77void draw_codepoint(Fontface* f, uint32_t* dst, int w, int h, int x,
78 int baseline, uint32_t cp, uint32_t fg)
79{
80 if (!f || !dst)
81 return;
82
83 if (!f->bdf || cp >= BDF_GLYPHS_MAX)
84 return;
85
86 BdfGlyph* g = &f->bdf[cp];
87 if (!g->valid)
88 return;
89
90 draw_bitmap(
91 dst, w, h, g->bmp, g->w, g->h, x + g->xoff,
92 baseline - g->yoff - g->h, fg
93 );
94}
95