mkfn: switch to ISC
[fbpad_mkfn.git] / mkfn_stb.c
blob2fe40e97841406d021be8cf6fd84263401f30db9
1 #include <ctype.h>
2 #include <fcntl.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include "stb_truetype.h"
7 #include "mkfn.h"
9 #define LIMIT(n, a, b) ((n) < (a) ? (a) : ((n) > (b) ? (b) : (n)))
11 static stbtt_fontinfo fn[NFONTS];
12 static float fn_vscale[NFONTS];
13 static float fn_hscale[NFONTS];
14 static int fn_size[NFONTS];
15 static int fn_bold[NFONTS];
16 static int fn_sr[NFONTS];
17 static int fn_sc[NFONTS];
18 static char *fn_buf[NFONTS];
19 static int fn_cnt;
21 void mkfn_dim(int *r, int *c)
23 int x0, y0, x1, y1;
24 stbtt_GetFontBoundingBox(&fn[0], &x0, &y0, &x1, &y1);
25 *r = (y1 - y0) * fn_vscale[0];
26 *c = (x1 - x0) * fn_hscale[0];
29 static int mkfn_base(int n, int rows)
31 int ascent, descent, linegap;
32 stbtt_GetFontVMetrics(&fn[n], &ascent, &descent, &linegap);
33 return ascent * fn_vscale[n] + (rows - fn_size[n]) / 2;
36 int mkfn_font(char *path, char *spec)
38 int n = fn_cnt;
39 int fd;
40 int hdpi = 100;
41 int vdpi = 100;
42 fd = open(path, O_RDONLY);
43 if (fd < 0)
44 return 1;
45 fn_buf[n] = malloc(1 << 20);
46 read(fd, fn_buf[n], 1 << 20);
47 close(fd);
48 if (!stbtt_InitFont(&fn[n], (void *) fn_buf[n],
49 stbtt_GetFontOffsetForIndex((void *) fn_buf[n], 0))) {
50 free(fn_buf[n]);
51 return 1;
53 fn_size[n] = 10;
54 while (spec && *spec) {
55 if (spec[0] == 'b')
56 fn_bold[n] = atoi(spec + 1);
57 if (spec[0] == 'v')
58 vdpi = atoi(spec + 1);
59 if (spec[0] == 'h')
60 hdpi = atoi(spec + 1);
61 if (spec[0] == 'r')
62 fn_sr[n] = atoi(spec + 1);
63 if (spec[0] == 'c')
64 fn_sc[n] = atoi(spec + 1);
65 if (spec[0] == 's')
66 fn_size[n] = atoi(spec + 1);
67 if (isdigit((unsigned char) spec[0]))
68 fn_size[n] = atoi(spec);
69 spec++;
70 while (*spec && strchr("0123456789+-", (unsigned char) *spec))
71 spec++;
73 fn_hscale[n] = stbtt_ScaleForPixelHeight(&fn[n], fn_size[n]) * hdpi / 100;
74 fn_vscale[n] = stbtt_ScaleForPixelHeight(&fn[n], fn_size[n]) * vdpi / 100;
75 fn_cnt++;
76 return 0;
79 static void mkfn_embolden(unsigned char *bits, int rows, int cols)
81 int i, j, k;
82 int n = 2;
83 for (i = 0; i < rows; i++) {
84 for (j = cols - n; j >= 0; j--) {
85 int idx = i * cols + j;
86 int val = 0;
87 for (k = 0; k < n; k++)
88 if (bits[idx + k] > val)
89 val = bits[idx + k];
90 bits[idx + n - 1] = val;
95 int mkfn_bitmap(char *dst, int c, int rows, int cols)
97 unsigned char *bits = (void *) dst;
98 int sr, sc; /* the starting row and column of the bitmap */
99 int nr, nc; /* the number of rows and columns to render */
100 int i;
101 int g = 0;
102 int x0, y0, x1, y1;
103 for (i = 0; i < fn_cnt; i++)
104 if ((g = stbtt_FindGlyphIndex(&fn[i], c & ~DWCHAR)) > 0)
105 break;
106 if (i == fn_cnt)
107 return 1;
108 if (!dst)
109 return 0;
110 stbtt_GetGlyphBitmapBox(&fn[i], g, fn_hscale[i], fn_vscale[i], &x0, &y0, &x1, &y1);
111 sr = LIMIT(mkfn_base(i, rows) + y0 + fn_sr[i], 0, rows);
112 sc = LIMIT(x0 + fn_sc[i], 0, cols);
113 nr = rows - sr;
114 nc = cols - sc;
115 memset(bits, 0, rows * cols);
116 stbtt_MakeGlyphBitmap(&fn[i], bits + sr * cols + sc, nc, nr, cols,
117 fn_hscale[i], fn_vscale[i], g);
118 if (fn_bold[i])
119 mkfn_embolden(bits, rows, cols);
120 return 0;
123 void mkfn_init(void)
127 void mkfn_free(void)
129 int i;
130 for (i = 0; i < fn_cnt; i++)
131 free(fn_buf[i]);