6 #include "stb_truetype.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
];
21 void mkfn_dim(int *r
, int *c
)
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
)
42 fd
= open(path
, O_RDONLY
);
45 fn_buf
[n
] = malloc(1 << 20);
46 read(fd
, fn_buf
[n
], 1 << 20);
48 if (!stbtt_InitFont(&fn
[n
], (void *) fn_buf
[n
],
49 stbtt_GetFontOffsetForIndex((void *) fn_buf
[n
], 0))) {
54 while (spec
&& *spec
) {
56 fn_bold
[n
] = atoi(spec
+ 1);
58 vdpi
= atoi(spec
+ 1);
60 hdpi
= atoi(spec
+ 1);
62 fn_sr
[n
] = atoi(spec
+ 1);
64 fn_sc
[n
] = atoi(spec
+ 1);
66 fn_size
[n
] = atoi(spec
+ 1);
67 if (isdigit((unsigned char) spec
[0]))
68 fn_size
[n
] = atoi(spec
);
70 while (*spec
&& strchr("0123456789+-", (unsigned char) *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;
79 static void mkfn_embolden(unsigned char *bits
, int rows
, int cols
)
83 for (i
= 0; i
< rows
; i
++) {
84 for (j
= cols
- n
; j
>= 0; j
--) {
85 int idx
= i
* cols
+ j
;
87 for (k
= 0; k
< n
; k
++)
88 if (bits
[idx
+ k
] > val
)
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 */
103 for (i
= 0; i
< fn_cnt
; i
++)
104 if ((g
= stbtt_FindGlyphIndex(&fn
[i
], c
& ~DWCHAR
)) > 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
);
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
);
119 mkfn_embolden(bits
, rows
, cols
);
130 for (i
= 0; i
< fn_cnt
; i
++)