commit 8485186a28217f2b38b2fd849ef5e0d09136f09d
parent 1dd7f2fe7e3f1ee61758b5e2ab31b47c32f236e6
Author: Brian Swetland <swetland@frotz.net>
Date: Sat, 22 Jun 2013 16:43:06 -0700
mkfont: improve glyph packing a bit, add output parameter
Diffstat:
M | tools/mkfont.cc | | | 89 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------- |
1 file changed, 61 insertions(+), 28 deletions(-)
diff --git a/tools/mkfont.cc b/tools/mkfont.cc
@@ -22,27 +22,58 @@
#include <util.h>
#include <texturefont.h>
+#include <algorithm>
+
/* from internal header... */
#define FT_PIX_FLOOR(x) ((x) & ~63)
#define FT_PIX_CEIL(x) FT_PIX_FLOOR((x) + 63)
+struct Glyph {
+ unsigned c;
+ unsigned h;
+};
+
+void get_bbox(FT_Outline *outline, FT_BBox *bb) {
+ FT_Outline_Get_CBox(outline, bb);
+ /* grid fit */
+ bb->xMin = FT_PIX_FLOOR(bb->xMin);
+ bb->yMin = FT_PIX_FLOOR(bb->yMin);
+ bb->xMax = FT_PIX_CEIL(bb->xMax);
+ bb->yMax = FT_PIX_CEIL(bb->yMax);
+ /* convert from 26.6 to pixel coords */
+ bb->xMin >>= 6;
+ bb->yMin >>= 6;
+ bb->xMax >>= 6;
+ bb->yMax >>= 6;
+}
+
+bool compare_glyphs(Glyph const &left, Glyph const &right) {
+ return left.h < right.h;
+}
+
+#define FIRST 0x20
+#define LAST 0x7F
+#define MAXDIM 1024
+
int main(int argc, char **argv) {
FT_Library ftl;
FT_Face face;
FT_Bitmap *bitmap;
- unsigned n;
+ unsigned i, n;
void *x;
-
+
FT_BBox bb;
FT_Bitmap bm;
- unsigned char data[1024 * 1024];
+ unsigned char data[MAXDIM * MAXDIM];
int w, h, tx, ty, nx, ny, rh, max;
CharInfo info[128];
+ Glyph list[LAST];
+ char tmp[256];
io_ignore_asset_paths();
- if (argc < 3)
- return -1;
+ if (argc < 4)
+ return error("usage: mkfont <truetypefont> <height> <outputname>");
if (FT_Init_FreeType(&ftl))
return -1;
@@ -57,6 +88,18 @@ int main(int argc, char **argv) {
if (FT_Set_Pixel_Sizes(face, 0, atoi(argv[2])))
return error("cannot set font size to %s\n", argv[2]);
+ for (n = FIRST; n < LAST; n++) {
+ if (FT_Load_Char(face, n, FT_LOAD_NO_BITMAP)) {
+ error("missing glyph for %d\n", n);
+ continue;
+ }
+ get_bbox(&face->glyph->outline, &bb);
+ list[n - FIRST].c = n;
+ list[n - FIRST].h = bb.yMax - bb.yMin;
+
+ }
+ std::sort(list, list + LAST - FIRST, compare_glyphs);
+
max = 128;
retry:
memset(data, 0, sizeof(data));
@@ -75,31 +118,17 @@ retry:
rh = 0;
printf("%dx%d texture...\n", max, max);
- for (n = 0x20; n < 0x7F; n++) {
+ for (i = 0; i < (LAST - FIRST); i++) {
+ n = list[i].c;
if (FT_Load_Char(face, n, FT_LOAD_NO_BITMAP)) {
error("missing glyph for %d\n", n);
continue;
}
- FT_Outline_Get_CBox(&face->glyph->outline, &bb);
- /* grid fit */
- bb.xMin = FT_PIX_FLOOR(bb.xMin);
- bb.yMin = FT_PIX_FLOOR(bb.yMin);
- bb.xMax = FT_PIX_CEIL(bb.xMax);
- bb.yMax = FT_PIX_CEIL(bb.yMax);
- /* convert from 26.6 to pixel coords */
- bb.xMin >>= 6;
- bb.yMin >>= 6;
- bb.xMax >>= 6;
- bb.yMax >>= 6;
+ get_bbox(&face->glyph->outline, &bb);
w = bb.xMax - bb.xMin + 1;
h = bb.yMax - bb.yMin + 1;
tx = -bb.xMin;
ty = -bb.yMin;
-#if 0
- fprintf(stderr,"%d,%d %d,%d adv %d\n",
- bb.xMin, bb.yMin, bb.xMax, bb.yMax,
- face->glyph->advance.x >> 6);
-#endif
if ((nx + w) >= max) {
nx = 1;
ny += rh + 1;
@@ -107,14 +136,14 @@ retry:
}
if ((ny + h) >= max) {
max *= 2;
- if (max > 1024) {
+ if (max > MAXDIM) {
fprintf(stderr,"oops! out of space\n");
return -1;
}
goto retry;
}
info[n].x = nx;
- info[n].y = max - ny - 1;
+ info[n].y = max - ny - h + 1;
info[n].w = w - 1;
info[n].h = h - 1;
info[n].dx = bb.xMin;
@@ -127,13 +156,17 @@ retry:
rh = h;
}
bitmap = &bm;
- save_png_gray("font.png", bitmap->buffer, bitmap->width, bitmap->rows);
+
+ sprintf(tmp, "%s.png", argv[3]);
+ save_png_gray(tmp, bitmap->buffer, bitmap->width, bitmap->rows);
FontInfo header;
header.magic = TEXTUREFONT_MAGIC;
- header.first = 0x20;
- header.count = 0x80;
+ header.first = FIRST;
+ header.count = LAST - FIRST;
header.unused = 0;
- FILE *fp = fopen("font.dat", "wb");
+
+ sprintf(tmp, "%s.dat", argv[3]);
+ FILE *fp = fopen(tmp, "wb");
if (!fp)
return error("cannot write font data");
if (fwrite(&header, sizeof(header), 1, fp) != 1)