graphics

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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:
Mtools/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)