Index: usr.bin/vtfontcvt/vtfontcvt.c =================================================================== --- usr.bin/vtfontcvt/vtfontcvt.c +++ usr.bin/vtfontcvt/vtfontcvt.c @@ -47,22 +47,23 @@ #include #include -#define VFNT_MAXGLYPHS 131072 -#define VFNT_MAXDIMENSION 128 +#define VFNT_MAXGLYPHS 131072 +#define VFNT_MAXDIMENSION 128 static unsigned int width = 8, wbytes, height = 16; struct glyph { - TAILQ_ENTRY(glyph) g_list; - SLIST_ENTRY(glyph) g_hash; - uint8_t *g_data; - unsigned int g_index; + TAILQ_ENTRY(glyph) g_list; + SLIST_ENTRY(glyph) g_hash; + uint8_t *g_data; + unsigned int g_index; }; -#define FONTCVT_NHASH 4096 +#define FONTCVT_NHASH 4096 TAILQ_HEAD(glyph_list, glyph); static SLIST_HEAD(, glyph) glyph_hash[FONTCVT_NHASH]; -static struct glyph_list glyphs[VFNT_MAPS] = { +static struct glyph_list glyphs[VFNT_MAPS] = +{ TAILQ_HEAD_INITIALIZER(glyphs[0]), TAILQ_HEAD_INITIALIZER(glyphs[1]), TAILQ_HEAD_INITIALIZER(glyphs[2]), @@ -71,14 +72,15 @@ static unsigned int glyph_total, glyph_count[4], glyph_unique, glyph_dupe; struct mapping { - TAILQ_ENTRY(mapping) m_list; - unsigned int m_char; - unsigned int m_length; - struct glyph *m_glyph; + TAILQ_ENTRY(mapping) m_list; + unsigned int m_char; + unsigned int m_length; + struct glyph *m_glyph; }; TAILQ_HEAD(mapping_list, mapping); -static struct mapping_list maps[VFNT_MAPS] = { +static struct mapping_list maps[VFNT_MAPS] = +{ TAILQ_HEAD_INITIALIZER(maps[0]), TAILQ_HEAD_INITIALIZER(maps[1]), TAILQ_HEAD_INITIALIZER(maps[2]), @@ -88,9 +90,9 @@ mapping_unique, mapping_dupe; enum output_format { - VT_FONT, /* default */ - VT_C_SOURCE, /* C source for built in fonts */ - VT_C_COMPRESSED /* C source with compressed font data */ + VT_FONT, /* default */ + VT_C_SOURCE, /* C source for built in fonts */ + VT_C_COMPRESSED /* C source with compressed font data */ }; struct whitelist { @@ -102,72 +104,74 @@ * Compressed font glyph list. To be used with boot loader, we need to have * ascii set and box drawing chars. */ -static struct whitelist c_list[] = { - { .c = 0, .len = 0 }, /* deault char */ - { .c = 0x20, .len = 0x5f }, - { .c = 0x2500, .len = 0 }, /* single frame */ - { .c = 0x2502, .len = 0 }, - { .c = 0x250c, .len = 0 }, - { .c = 0x2510, .len = 0 }, - { .c = 0x2514, .len = 0 }, - { .c = 0x2518, .len = 0 }, - { .c = 0x2550, .len = 1 }, /* double frame */ - { .c = 0x2554, .len = 0 }, - { .c = 0x2557, .len = 0 }, - { .c = 0x255a, .len = 0 }, - { .c = 0x255d, .len = 0 }, +static struct whitelist c_list[] = +{ + { .c = 0, .len = 0 }, /* deault char */ + { .c = 0x20, .len = 0x5f }, + { .c = 0x2500, .len = 0 }, /* single frame */ + { .c = 0x2502, .len = 0 }, + { .c = 0x250c, .len = 0 }, + { .c = 0x2510, .len = 0 }, + { .c = 0x2514, .len = 0 }, + { .c = 0x2518, .len = 0 }, + { .c = 0x2550, .len = 1 },/* double frame */ + { .c = 0x2554, .len = 0 }, + { .c = 0x2557, .len = 0 }, + { .c = 0x255a, .len = 0 }, + { .c = 0x255d, .len = 0 }, }; /* * Uncompressed source. For x86 we need cp437 so the vga text mode * can program font into the vga card. */ -static struct whitelist s_list[] = { - { .c = 0, .len = 0 }, /* deault char */ - { .c = 0x20, .len = 0x5f }, /* ascii set */ - { .c = 0xA0, .len = 0x5f }, /* latin 1 */ - { .c = 0x0192, .len = 0 }, - { .c = 0x0332, .len = 0 }, /* composing lower line */ - { .c = 0x0393, .len = 0 }, - { .c = 0x0398, .len = 0 }, - { .c = 0x03A3, .len = 0 }, - { .c = 0x03A6, .len = 0 }, - { .c = 0x03A9, .len = 0 }, - { .c = 0x03B1, .len = 1 }, - { .c = 0x03B4, .len = 0 }, - { .c = 0x03C0, .len = 0 }, - { .c = 0x03C3, .len = 0 }, - { .c = 0x03C4, .len = 0 }, - { .c = 0x207F, .len = 0 }, - { .c = 0x20A7, .len = 0 }, - { .c = 0x2205, .len = 0 }, - { .c = 0x220A, .len = 0 }, - { .c = 0x2219, .len = 1 }, - { .c = 0x221E, .len = 0 }, - { .c = 0x2229, .len = 0 }, - { .c = 0x2248, .len = 0 }, - { .c = 0x2261, .len = 0 }, - { .c = 0x2264, .len = 1 }, - { .c = 0x2310, .len = 0 }, - { .c = 0x2320, .len = 1 }, - { .c = 0x2500, .len = 0 }, - { .c = 0x2502, .len = 0 }, - { .c = 0x250C, .len = 0 }, - { .c = 0x2510, .len = 0 }, - { .c = 0x2514, .len = 0 }, - { .c = 0x2518, .len = 0 }, - { .c = 0x251C, .len = 0 }, - { .c = 0x2524, .len = 0 }, - { .c = 0x252C, .len = 0 }, - { .c = 0x2534, .len = 0 }, - { .c = 0x253C, .len = 0 }, - { .c = 0x2550, .len = 0x1c }, - { .c = 0x2580, .len = 0 }, - { .c = 0x2584, .len = 0 }, - { .c = 0x2588, .len = 0 }, - { .c = 0x258C, .len = 0 }, - { .c = 0x2590, .len = 3 }, - { .c = 0x25A0, .len = 0 }, +static struct whitelist s_list[] = +{ + { .c = 0, .len = 0 }, /* deault char */ + { .c = 0x20, .len = 0x5f }, /* ascii set */ + { .c = 0xA0, .len = 0x5f }, /* latin 1 */ + { .c = 0x0192, .len = 0 }, + { .c = 0x0332, .len = 0 }, /* composing lower line */ + { .c = 0x0393, .len = 0 }, + { .c = 0x0398, .len = 0 }, + { .c = 0x03A3, .len = 0 }, + { .c = 0x03A6, .len = 0 }, + { .c = 0x03A9, .len = 0 }, + { .c = 0x03B1, .len = 1 }, + { .c = 0x03B4, .len = 0 }, + { .c = 0x03C0, .len = 0 }, + { .c = 0x03C3, .len = 0 }, + { .c = 0x03C4, .len = 0 }, + { .c = 0x207F, .len = 0 }, + { .c = 0x20A7, .len = 0 }, + { .c = 0x2205, .len = 0 }, + { .c = 0x220A, .len = 0 }, + { .c = 0x2219, .len = 1 }, + { .c = 0x221E, .len = 0 }, + { .c = 0x2229, .len = 0 }, + { .c = 0x2248, .len = 0 }, + { .c = 0x2261, .len = 0 }, + { .c = 0x2264, .len = 1 }, + { .c = 0x2310, .len = 0 }, + { .c = 0x2320, .len = 1 }, + { .c = 0x2500, .len = 0 }, + { .c = 0x2502, .len = 0 }, + { .c = 0x250C, .len = 0 }, + { .c = 0x2510, .len = 0 }, + { .c = 0x2514, .len = 0 }, + { .c = 0x2518, .len = 0 }, + { .c = 0x251C, .len = 0 }, + { .c = 0x2524, .len = 0 }, + { .c = 0x252C, .len = 0 }, + { .c = 0x2534, .len = 0 }, + { .c = 0x253C, .len = 0 }, + { .c = 0x2550, .len = 0x1c }, + { .c = 0x2580, .len = 0 }, + { .c = 0x2584, .len = 0 }, + { .c = 0x2588, .len = 0 }, + { .c = 0x258C, .len = 0 }, + { .c = 0x2590, .len = 3 }, + { .c = 0x25A0, .len = 0 }, }; static bool filter = true; @@ -179,23 +183,25 @@ static void usage(void) { - (void)fprintf(stderr, "usage: vtfontcvt " "[-n] [-f font|source|compressed-source] [-w width] " "[-h height]\n\t[-v] normal.bdf [bold.bdf] out.fnt\n"); exit(1); } + static void * xmalloc(size_t size) { void *m; - if ((m = calloc(1, size)) == NULL) + if ((m = calloc(1, size)) == NULL) { errx(1, "memory allocation failure"); + } return (m); } + static int add_mapping(struct glyph *gl, unsigned int c, unsigned int map_idx) { @@ -210,13 +216,13 @@ mp->m_length = 0; ml = &maps[map_idx]; - if (TAILQ_LAST(ml, mapping_list) == NULL || - TAILQ_LAST(ml, mapping_list)->m_char < c) { + if ((TAILQ_LAST(ml, mapping_list) == NULL) || + (TAILQ_LAST(ml, mapping_list)->m_char < c)) { /* Common case: empty list or new char at end of list. */ TAILQ_INSERT_TAIL(ml, mp, m_list); } else { /* Find insertion point for char; cannot be at end. */ - TAILQ_FOREACH(mp_temp, ml, m_list) { + TAILQ_FOREACH (mp_temp, ml, m_list) { if (mp_temp->m_char >= c) { TAILQ_INSERT_BEFORE(mp_temp, mp, m_list); break; @@ -230,6 +236,7 @@ return (0); } + static int dedup_mapping(unsigned int map_idx) { @@ -238,14 +245,17 @@ assert(map_idx == VFNT_MAP_BOLD || map_idx == VFNT_MAP_BOLD_RIGHT); mp_normal = TAILQ_FIRST(&maps[normal_map_idx]); - TAILQ_FOREACH_SAFE(mp_bold, &maps[map_idx], m_list, mp_temp) { - while (mp_normal->m_char < mp_bold->m_char) + TAILQ_FOREACH_SAFE (mp_bold, &maps[map_idx], m_list, mp_temp) { + while (mp_normal->m_char < mp_bold->m_char) { mp_normal = TAILQ_NEXT(mp_normal, m_list); - if (mp_bold->m_char != mp_normal->m_char) + } + if (mp_bold->m_char != mp_normal->m_char) { errx(1, "Character %u not in normal font!", mp_bold->m_char); - if (mp_bold->m_glyph != mp_normal->m_glyph) + } + if (mp_bold->m_glyph != mp_normal->m_glyph) { continue; + } /* No mapping is needed if it's equal to the normal mapping. */ TAILQ_REMOVE(&maps[map_idx], mp_bold, m_list); @@ -255,6 +265,7 @@ return (0); } + static struct glyph * add_glyph(const uint8_t *bytes, unsigned int map_idx, int fallback) { @@ -266,7 +277,7 @@ /* Return existing glyph if we have an identical one. */ hash = fnv_32_buf(bytes, wbytes * height, FNV1_32_INIT) % FONTCVT_NHASH; - SLIST_FOREACH(gl, &glyph_hash[hash], g_hash) { + SLIST_FOREACH (gl, &glyph_hash[hash], g_hash) { if (memcmp(gl->g_data, bytes, wbytes * height) == 0) { glyph_dupe++; return (gl); @@ -277,44 +288,51 @@ gl = xmalloc(sizeof *gl); gl->g_data = xmalloc(wbytes * height); memcpy(gl->g_data, bytes, wbytes * height); - if (fallback) + if (fallback) { TAILQ_INSERT_HEAD(&glyphs[map_idx], gl, g_list); - else + } else { TAILQ_INSERT_TAIL(&glyphs[map_idx], gl, g_list); + } SLIST_INSERT_HEAD(&glyph_hash[hash], gl, g_hash); glyph_unique++; - if (glyph_unique > VFNT_MAXGLYPHS) + if (glyph_unique > VFNT_MAXGLYPHS) { errx(1, "too many glyphs (%u)", glyph_unique); + } return (gl); } + static bool check_whitelist(unsigned c) { struct whitelist *w = NULL; int i, n = 0; - if (filter == false) + if (filter == false) { return (true); + } if (format == VT_C_SOURCE) { w = s_list; - n = sizeof (s_list) / sizeof (s_list[0]); + n = sizeof(s_list) / sizeof(s_list[0]); } if (format == VT_C_COMPRESSED) { w = c_list; - n = sizeof (c_list) / sizeof (c_list[0]); + n = sizeof(c_list) / sizeof(c_list[0]); } - if (w == NULL) + if (w == NULL) { return (true); + } for (i = 0; i < n; i++) { - if (c >= w[i].c && c <= w[i].c + w[i].len) + if ((c >= w[i].c) && (c <= w[i].c + w[i].len)) { return (true); + } } return (false); } + static int add_char(unsigned curchar, unsigned map_idx, uint8_t *bytes, uint8_t *bytes_r) { @@ -322,21 +340,25 @@ /* Prevent adding two glyphs for 0xFFFD */ if (curchar == 0xFFFD) { - if (map_idx < VFNT_MAP_BOLD) + if (map_idx < VFNT_MAP_BOLD) { gl = add_glyph(bytes, 0, 1); - } else if (filter == false || curchar >= 0x20) { + } + } else if ((filter == false) || (curchar >= 0x20)) { gl = add_glyph(bytes, map_idx, 0); - if (add_mapping(gl, curchar, map_idx) != 0) + if (add_mapping(gl, curchar, map_idx) != 0) { return (1); + } if (bytes_r != NULL) { gl = add_glyph(bytes_r, map_idx + 1, 0); - if (add_mapping(gl, curchar, map_idx + 1) != 0) + if (add_mapping(gl, curchar, map_idx + 1) != 0) { return (1); + } } } return (0); } + /* * Right-shift glyph row. */ @@ -346,13 +368,16 @@ ssize_t i, off_byte = shift / 8; size_t off_bit = shift % 8; - if (shift == 0) + if (shift == 0) { return; - for (i = len - 1; i >= 0; i--) + } + for (i = len - 1; i >= 0; i--) { buf[i] = (i >= off_byte ? buf[i - off_byte] >> off_bit : 0) | (i > off_byte ? buf[i - off_byte - 1] << (8 - off_bit) : 0); + } } + /* * Split double-width characters into left and right half. Single-width * characters in _left_ only. @@ -381,23 +406,28 @@ return (0); } + static void set_height(int h) { - if (h <= 0 || h > VFNT_MAXDIMENSION) + if ((h <= 0) || (h > VFNT_MAXDIMENSION)) { errx(1, "invalid height %d", h); + } height = h; } + static void set_width(int w) { - if (w <= 0 || w > VFNT_MAXDIMENSION) + if ((w <= 0) || (w > VFNT_MAXDIMENSION)) { errx(1, "invalid width %d", w); + } width = w; wbytes = howmany(width, 8); } + static int parse_bdf(FILE *fp, unsigned int map_idx) { @@ -405,8 +435,8 @@ size_t length; uint8_t *line, *bytes, *bytes_r; unsigned int curchar = 0, i, j, linenum = 0, bbwbytes; - int bbw, bbh, bbox, bboy; /* Glyph bounding box. */ - int fbbw = 0, fbbh, fbbox, fbboy; /* Font bounding box. */ + int bbw, bbh, bbox, bboy; /* Glyph bounding box. */ + int fbbw = 0, fbbh, fbbox, fbboy; /* Font bounding box. */ int dwidth = 0, dwy = 0; int rv = -1; char spc = '\0'; @@ -432,18 +462,21 @@ } } else if (strncmp(ln, "FONTBOUNDINGBOX ", 16) == 0) { if (sscanf(ln + 16, "%d %d %d %d", &fbbw, &fbbh, &fbbox, - &fbboy) != 4) + &fbboy) != 4) { errx(1, "invalid FONTBOUNDINGBOX at line %u", linenum); + } set_width(fbbw); set_height(fbbh); break; } } - if (fbbw == 0) + if (fbbw == 0) { errx(1, "broken font header"); - if (spc != 'c' && spc != 'C') + } + if ((spc != 'c') && (spc != 'C')) { errx(1, "font spacing \"C\" (character cell) required"); + } /* Step 2: Validate DWIDTH (Device Width) of all glyphs. */ while ((ln = fgetln(fp, &length)) != NULL) { @@ -451,13 +484,18 @@ ln[length - 1] = '\0'; if (strncmp(ln, "DWIDTH ", 7) == 0) { - if (sscanf(ln + 7, "%d %d", &dwidth, &dwy) != 2) + if (sscanf(ln + 7, "%d %d", &dwidth, &dwy) != 2) { errx(1, "invalid DWIDTH at line %u", linenum); - if (dwy != 0 || (dwidth != fbbw && dwidth * 2 != fbbw)) - errx(1, "bitmap with unsupported DWIDTH %d %d at line %u", + } + if ((dwy != 0) || + ((dwidth != fbbw) && (dwidth * 2 != fbbw))) { + errx(1, + "bitmap with unsupported DWIDTH %d %d at line %u", dwidth, dwy, linenum); - if (dwidth < fbbw) + } + if (dwidth < fbbw) { set_width(dwidth); + } } } @@ -479,19 +517,24 @@ dwidth = atoi(ln + 7); } else if (strncmp(ln, "BBX ", 4) == 0) { if (sscanf(ln + 4, "%d %d %d %d", &bbw, &bbh, &bbox, - &bboy) != 4) + &bboy) != 4) { errx(1, "invalid BBX at line %u", linenum); - if (bbw < 1 || bbh < 1 || bbw > fbbw || bbh > fbbh || - bbox < fbbox || bboy < fbboy || - bbh + bboy > fbbh + fbboy) - errx(1, "broken bitmap with BBX %d %d %d %d at line %u", + } + if ((bbw < 1) || (bbh < 1) || (bbw > fbbw) || + (bbh > fbbh) || + (bbox < fbbox) || (bboy < fbboy) || + (bbh + bboy > fbbh + fbboy)) { + errx(1, + "broken bitmap with BBX %d %d %d %d at line %u", bbw, bbh, bbox, bboy, linenum); + } bbwbytes = howmany(bbw, 8); - } else if (strncmp(ln, "BITMAP", 6) == 0 && - (ln[6] == ' ' || ln[6] == '\0')) { - if (dwidth == 0 || bbw == 0 || bbh == 0) + } else if ((strncmp(ln, "BITMAP", 6) == 0) && + ((ln[6] == ' ') || (ln[6] == '\0'))) { + if ((dwidth == 0) || (bbw == 0) || (bbh == 0)) { errx(1, "broken char header at line %u!", linenum); + } memset(bytes, 0, wbytes * height); memset(bytes_r, 0, wbytes * height); @@ -503,36 +546,42 @@ */ for (i = (fbbh + fbboy) - (bbh + bboy); i < (unsigned int)((fbbh + fbboy) - bboy); i++) { - if ((ln = fgetln(fp, &length)) == NULL) + if ((ln = fgetln(fp, &length)) == NULL) { errx(1, "unexpected EOF"); + } linenum++; ln[length - 1] = '\0'; - if (strcmp(ln, "ENDCHAR") == 0) + if (strcmp(ln, "ENDCHAR") == 0) { break; - if (strlen(ln) < bbwbytes * 2) + } + if (strlen(ln) < bbwbytes * 2) { errx(1, "broken bitmap at line %u", linenum); + } memset(line, 0, wbytes * 2); for (j = 0; j < bbwbytes; j++) { unsigned int val; if (sscanf(ln + j * 2, "%2x", &val) == - 0) + 0) { break; + } *(line + j) = (uint8_t)val; } rshift_row(line, wbytes * 2, bbox - fbbox); rv = split_row(bytes + i * wbytes, - bytes_r + i * wbytes, line, dwidth); - if (rv != 0) + bytes_r + i * wbytes, line, dwidth); + if (rv != 0) { goto out; + } } if (check_whitelist(curchar) == true) { rv = add_char(curchar, map_idx, bytes, - dwidth > (int)width ? bytes_r : NULL); - if (rv != 0) + dwidth > (int)width ? bytes_r : NULL); + if (rv != 0) { goto out; + } } dwidth = bbw = bbh = 0; @@ -546,6 +595,7 @@ return (rv); } + static int parse_hex(FILE *fp, unsigned int map_idx) { @@ -559,12 +609,16 @@ ln[length - 1] = '\0'; if (strncmp(ln, "# Height: ", 10) == 0) { - if (bytes != NULL) - errx(1, "malformed input: Height tag after font data"); + if (bytes != NULL) { + errx(1, + "malformed input: Height tag after font data"); + } set_height(atoi(ln + 10)); } else if (strncmp(ln, "# Width: ", 9) == 0) { - if (bytes != NULL) - errx(1, "malformed input: Width tag after font data"); + if (bytes != NULL) { + errx(1, + "malformed input: Width tag after font data"); + } set_width(atoi(ln + 9)); } else if (sscanf(ln, "%6x:", &curchar)) { if (bytes == NULL) { @@ -575,13 +629,14 @@ /* ln is guaranteed to have a colon here. */ p = strchr(ln, ':') + 1; chars_per_row = strlen(p) / height; - if (chars_per_row < wbytes * 2) + if (chars_per_row < wbytes * 2) { errx(1, "malformed input: broken bitmap, character %06x", curchar); + } gwidth = width * 2; gwbytes = howmany(gwidth, 8); - if (chars_per_row < gwbytes * 2 || gwidth <= 8) { + if ((chars_per_row < gwbytes * 2) || (gwidth <= 8)) { gwidth = width; /* Single-width character. */ gwbytes = wbytes; } @@ -589,22 +644,26 @@ for (i = 0; i < height; i++) { for (j = 0; j < gwbytes; j++) { unsigned int val; - if (sscanf(p + j * 2, "%2x", &val) == 0) + if (sscanf(p + j * 2, "%2x", + &val) == 0) { break; + } *(line + j) = (uint8_t)val; } rv = split_row(bytes + i * wbytes, - bytes_r + i * wbytes, line, gwidth); - if (rv != 0) + bytes_r + i * wbytes, line, gwidth); + if (rv != 0) { goto out; + } p += gwbytes * 2; } if (check_whitelist(curchar) == true) { rv = add_char(curchar, map_idx, bytes, - gwidth != width ? bytes_r : NULL); - if (rv != 0) + gwidth != width ? bytes_r : NULL); + if (rv != 0) { goto out; + } } } } @@ -615,6 +674,7 @@ return (rv); } + static int parse_file(const char *filename, unsigned int map_idx) { @@ -628,25 +688,30 @@ return (1); } len = strlen(filename); - if (len > 4 && strcasecmp(filename + len - 4, ".hex") == 0) + if ((len > 4) && (strcasecmp(filename + len - 4, ".hex") == 0)) { rv = parse_hex(fp, map_idx); - else + } else { rv = parse_bdf(fp, map_idx); + } fclose(fp); return (rv); } + static void number_glyphs(void) { struct glyph *gl; unsigned int i, idx = 0; - for (i = 0; i < VFNT_MAPS; i++) - TAILQ_FOREACH(gl, &glyphs[i], g_list) + for (i = 0; i < VFNT_MAPS; i++) { + TAILQ_FOREACH (gl, &glyphs[i], g_list) { gl->g_index = idx++; + } + } } + /* Note we only deal with byte stream here. */ static size_t write_glyph_source(const void *ptr, size_t size, size_t nitems, FILE *stream) @@ -657,18 +722,22 @@ size *= nitems; for (i = 0; i < size; i++) { if ((i % wbytes) == 0) { - if (fprintf(stream, "\n") < 0) + if (fprintf(stream, "\n") < 0) { return (0); + } } - if (fprintf(stream, "0x%02x, ", data[i]) < 0) + if (fprintf(stream, "0x%02x, ", data[i]) < 0) { return (0); + } } - if (fprintf(stream, "\n") < 0) + if (fprintf(stream, "\n") < 0) { nitems = 0; + } return (nitems); } + /* Write to buffer */ static size_t write_glyph_buf(const void *ptr, size_t size, size_t nitems, @@ -677,12 +746,13 @@ static size_t index = 0; size *= nitems; - (void) memmove(uncompressed + index, ptr, size); + (void)memmove(uncompressed + index, ptr, size); index += size; return (nitems); } + static int write_glyphs(FILE *fp, vt_write cb) { @@ -690,13 +760,16 @@ unsigned int i; for (i = 0; i < VFNT_MAPS; i++) { - TAILQ_FOREACH(gl, &glyphs[i], g_list) - if (cb(gl->g_data, wbytes * height, 1, fp) != 1) + TAILQ_FOREACH (gl, &glyphs[i], g_list) { + if (cb(gl->g_data, wbytes * height, 1, fp) != 1) { return (1); + } + } } return (0); } + static void fold_mappings(unsigned int map_idx) { @@ -706,15 +779,17 @@ mp = mbase = TAILQ_FIRST(ml); for (mp = mbase = TAILQ_FIRST(ml); mp != NULL; mp = mn) { mn = TAILQ_NEXT(mp, m_list); - if (mn != NULL && mn->m_char == mp->m_char + 1 && - mn->m_glyph->g_index == mp->m_glyph->g_index + 1) + if ((mn != NULL) && (mn->m_char == mp->m_char + 1) && + (mn->m_glyph->g_index == mp->m_glyph->g_index + 1)) { continue; + } mbase->m_length = mp->m_char - mbase->m_char + 1; mbase = mp = mn; map_folded_count[map_idx]++; } } + static int write_mappings(FILE *fp, unsigned int map_idx) { @@ -723,21 +798,23 @@ vfnt_map_t fm; unsigned int i = 0, j = 0; - TAILQ_FOREACH(mp, ml, m_list) { + TAILQ_FOREACH (mp, ml, m_list) { j++; if (mp->m_length > 0) { i += mp->m_length; fm.vfm_src = htobe32(mp->m_char); fm.vfm_dst = htobe16(mp->m_glyph->g_index); fm.vfm_len = htobe16(mp->m_length - 1); - if (fwrite(&fm, sizeof fm, 1, fp) != 1) + if (fwrite(&fm, sizeof fm, 1, fp) != 1) { return (1); + } } } assert(i == j); return (0); } + static int write_source_mappings(FILE *fp, unsigned int map_idx) { @@ -745,26 +822,29 @@ struct mapping *mp; unsigned int i = 0, j = 0; - TAILQ_FOREACH(mp, ml, m_list) { + TAILQ_FOREACH (mp, ml, m_list) { j++; if (mp->m_length > 0) { i += mp->m_length; if (fprintf(fp, "\t{ 0x%08x, 0x%04x, 0x%04x },\n", mp->m_char, mp->m_glyph->g_index, - mp->m_length - 1) < 0) + mp->m_length - 1) < 0) { return (1); + } } } assert(i == j); return (0); } + static int write_fnt(const char *filename) { FILE *fp; - struct font_header fh = { - .fh_magic = FONT_HEADER_MAGIC, + struct font_header fh = + { + .fh_magic = FONT_HEADER_MAGIC, }; fp = fopen(filename, "wb"); @@ -786,11 +866,11 @@ return (1); } - if (write_glyphs(fp, &fwrite) != 0 || - write_mappings(fp, VFNT_MAP_NORMAL) != 0 || - write_mappings(fp, VFNT_MAP_NORMAL_RIGHT) != 0 || - write_mappings(fp, VFNT_MAP_BOLD) != 0 || - write_mappings(fp, VFNT_MAP_BOLD_RIGHT) != 0) { + if ((write_glyphs(fp, &fwrite) != 0) || + (write_mappings(fp, VFNT_MAP_NORMAL) != 0) || + (write_mappings(fp, VFNT_MAP_NORMAL_RIGHT) != 0) || + (write_mappings(fp, VFNT_MAP_BOLD) != 0) || + (write_mappings(fp, VFNT_MAP_BOLD_RIGHT) != 0)) { perror(filename); fclose(fp); return (1); @@ -800,6 +880,7 @@ return (0); } + static int write_fnt_source(bool lz4, const char *filename) { @@ -820,142 +901,182 @@ compressed = xmalloc(uncompressed_size); } if (fprintf(fp, "/* Generated %ux%u console font source. */\n\n", - width, height) < 0) + width, height) < 0) { goto done; - if (fprintf(fp, "#include \n") < 0) + } + if (fprintf(fp, "#include \n") < 0) { goto done; - if (fprintf(fp, "#include \n") < 0) + } + if (fprintf(fp, "#include \n") < 0) { goto done; - if (fprintf(fp, "#include \n\n") < 0) + } + if (fprintf(fp, "#include \n\n") < 0) { goto done; + } /* Write font bytes. */ if (fprintf(fp, "static uint8_t FONTDATA_%ux%u[] = {\n", - width, height) < 0) + width, height) < 0) { goto done; + } if (lz4 == true) { - if (write_glyphs(fp, &write_glyph_buf) != 0) + if (write_glyphs(fp, &write_glyph_buf) != 0) { goto done; + } compressed_size = lz4_compress(uncompressed, compressed, - uncompressed_size, compressed_size, 0); - if (write_glyph_source(compressed, compressed_size, 1, fp) != 1) + uncompressed_size, compressed_size, 0); + if (write_glyph_source(compressed, compressed_size, 1, + fp) != 1) { goto done; + } free(uncompressed); free(compressed); } else { - if (write_glyphs(fp, &write_glyph_source) != 0) + if (write_glyphs(fp, &write_glyph_source) != 0) { goto done; + } + } + if (fprintf(fp, "};\n\n") < 0) { + goto done; } - if (fprintf(fp, "};\n\n") < 0) - goto done; /* Write font maps. */ if (!TAILQ_EMPTY(&maps[VFNT_MAP_NORMAL])) { if (fprintf(fp, "static vfnt_map_t " - "FONTMAP_NORMAL_%ux%u[] = {\n", width, height) < 0) + "FONTMAP_NORMAL_%ux%u[] = {\n", width, height) < 0) { goto done; - if (write_source_mappings(fp, VFNT_MAP_NORMAL) != 0) + } + if (write_source_mappings(fp, VFNT_MAP_NORMAL) != 0) { goto done; - if (fprintf(fp, "};\n\n") < 0) + } + if (fprintf(fp, "};\n\n") < 0) { goto done; + } } if (!TAILQ_EMPTY(&maps[VFNT_MAP_NORMAL_RIGHT])) { if (fprintf(fp, "static vfnt_map_t " - "FONTMAP_NORMAL_RH_%ux%u[] = {\n", width, height) < 0) + "FONTMAP_NORMAL_RH_%ux%u[] = {\n", width, height) < 0) { goto done; - if (write_source_mappings(fp, VFNT_MAP_NORMAL_RIGHT) != 0) + } + if (write_source_mappings(fp, VFNT_MAP_NORMAL_RIGHT) != 0) { goto done; - if (fprintf(fp, "};\n\n") < 0) + } + if (fprintf(fp, "};\n\n") < 0) { goto done; + } } if (!TAILQ_EMPTY(&maps[VFNT_MAP_BOLD])) { if (fprintf(fp, "static vfnt_map_t " - "FONTMAP_BOLD_%ux%u[] = {\n", width, height) < 0) + "FONTMAP_BOLD_%ux%u[] = {\n", width, height) < 0) { goto done; - if (write_source_mappings(fp, VFNT_MAP_BOLD) != 0) + } + if (write_source_mappings(fp, VFNT_MAP_BOLD) != 0) { goto done; - if (fprintf(fp, "};\n\n") < 0) + } + if (fprintf(fp, "};\n\n") < 0) { goto done; + } } if (!TAILQ_EMPTY(&maps[VFNT_MAP_BOLD_RIGHT])) { if (fprintf(fp, "static vfnt_map_t " - "FONTMAP_BOLD_RH_%ux%u[] = {\n", width, height) < 0) + "FONTMAP_BOLD_RH_%ux%u[] = {\n", width, height) < 0) { goto done; - if (write_source_mappings(fp, VFNT_MAP_BOLD_RIGHT) != 0) + } + if (write_source_mappings(fp, VFNT_MAP_BOLD_RIGHT) != 0) { goto done; - if (fprintf(fp, "};\n\n") < 0) + } + if (fprintf(fp, "};\n\n") < 0) { goto done; + } } /* Write struct font. */ if (fprintf(fp, "struct vt_font font_%ux%u = {\n", - width, height) < 0) + width, height) < 0) { goto done; - if (fprintf(fp, "\t.vf_map\t= {\n") < 0) + } + if (fprintf(fp, "\t.vf_map\t= {\n") < 0) { goto done; + } if (TAILQ_EMPTY(&maps[VFNT_MAP_NORMAL])) { - if (fprintf(fp, "\t\t\tNULL,\n") < 0) + if (fprintf(fp, "\t\t\tNULL,\n") < 0) { goto done; + } } else { if (fprintf(fp, "\t\t\tFONTMAP_NORMAL_%ux%u,\n", - width, height) < 0) + width, height) < 0) { goto done; + } } if (TAILQ_EMPTY(&maps[VFNT_MAP_NORMAL_RIGHT])) { - if (fprintf(fp, "\t\t\tNULL,\n") < 0) + if (fprintf(fp, "\t\t\tNULL,\n") < 0) { goto done; + } } else { if (fprintf(fp, "\t\t\tFONTMAP_NORMAL_RH_%ux%u,\n", - width, height) < 0) + width, height) < 0) { goto done; + } } if (TAILQ_EMPTY(&maps[VFNT_MAP_BOLD])) { - if (fprintf(fp, "\t\t\tNULL,\n") < 0) + if (fprintf(fp, "\t\t\tNULL,\n") < 0) { goto done; + } } else { if (fprintf(fp, "\t\t\tFONTMAP_BOLD_%ux%u,\n", - width, height) < 0) + width, height) < 0) { goto done; + } } if (TAILQ_EMPTY(&maps[VFNT_MAP_BOLD_RIGHT])) { - if (fprintf(fp, "\t\t\tNULL\n") < 0) + if (fprintf(fp, "\t\t\tNULL\n") < 0) { goto done; + } } else { if (fprintf(fp, "\t\t\tFONTMAP_BOLD_RH_%ux%u\n", - width, height) < 0) + width, height) < 0) { goto done; + } } - if (fprintf(fp, "\t\t},\n") < 0) + if (fprintf(fp, "\t\t},\n") < 0) { goto done; + } if (lz4 == true) { - if (fprintf(fp, "\t.vf_bytes\t= NULL,\n") < 0) + if (fprintf(fp, "\t.vf_bytes\t= NULL,\n") < 0) { goto done; + } } else { if (fprintf(fp, "\t.vf_bytes\t= FONTDATA_%ux%u,\n", width, height) < 0) { goto done; } } - if (fprintf(fp, "\t.vf_width\t= %u,\n", width) < 0) + if (fprintf(fp, "\t.vf_width\t= %u,\n", width) < 0) { goto done; - if (fprintf(fp, "\t.vf_height\t= %u,\n", height) < 0) + } + if (fprintf(fp, "\t.vf_height\t= %u,\n", height) < 0) { goto done; + } if (fprintf(fp, "\t.vf_map_count\t= { %u, %u, %u, %u }\n", map_folded_count[0], map_folded_count[1], map_folded_count[2], map_folded_count[3]) < 0) { goto done; } - if (fprintf(fp, "};\n\n") < 0) + if (fprintf(fp, "};\n\n") < 0) { goto done; + } /* Write bitmap data. */ if (fprintf(fp, "vt_font_bitmap_data_t font_data_%ux%u = {\n", - width, height) < 0) + width, height) < 0) { goto done; - if (fprintf(fp, "\t.vfbd_width\t= %u,\n", width) < 0) + } + if (fprintf(fp, "\t.vfbd_width\t= %u,\n", width) < 0) { goto done; - if (fprintf(fp, "\t.vfbd_height\t= %u,\n", height) < 0) + } + if (fprintf(fp, "\t.vfbd_height\t= %u,\n", height) < 0) { goto done; + } if (lz4 == true) { if (fprintf(fp, "\t.vfbd_compressed_size\t= %zu,\n", compressed_size) < 0) { @@ -970,68 +1091,75 @@ goto done; } } else { - if (fprintf(fp, "\t.vfbd_compressed_size\t= 0,\n") < 0) + if (fprintf(fp, "\t.vfbd_compressed_size\t= 0,\n") < 0) { goto done; + } if (fprintf(fp, "\t.vfbd_uncompressed_size\t= %zu,\n", uncompressed_size) < 0) { goto done; } - if (fprintf(fp, "\t.vfbd_compressed_data\t= NULL,\n") < 0) + if (fprintf(fp, "\t.vfbd_compressed_data\t= NULL,\n") < 0) { goto done; + } } - if (fprintf(fp, "\t.vfbd_font = &font_%ux%u\n", width, height) < 0) + if (fprintf(fp, "\t.vfbd_font = &font_%ux%u\n", width, height) < 0) { goto done; - if (fprintf(fp, "};\n") < 0) + } + if (fprintf(fp, "};\n") < 0) { goto done; + } rv = 0; done: - if (rv != 0) + if (rv != 0) { perror(filename); + } fclose(fp); return (0); } + static void print_font_info(void) { printf( -"Statistics:\n" -"- width: %6u\n" -"- height: %6u\n" -"- glyph_total: %6u\n" -"- glyph_normal: %6u\n" -"- glyph_normal_right: %6u\n" -"- glyph_bold: %6u\n" -"- glyph_bold_right: %6u\n" -"- glyph_unique: %6u\n" -"- glyph_dupe: %6u\n" -"- mapping_total: %6u\n" -"- mapping_normal: %6u\n" -"- mapping_normal_folded: %6u\n" -"- mapping_normal_right: %6u\n" -"- mapping_normal_right_folded: %6u\n" -"- mapping_bold: %6u\n" -"- mapping_bold_folded: %6u\n" -"- mapping_bold_right: %6u\n" -"- mapping_bold_right_folded: %6u\n" -"- mapping_unique: %6u\n" -"- mapping_dupe: %6u\n", - width, height, - glyph_total, - glyph_count[0], - glyph_count[1], - glyph_count[2], - glyph_count[3], - glyph_unique, glyph_dupe, - mapping_total, - map_count[0], map_folded_count[0], - map_count[1], map_folded_count[1], - map_count[2], map_folded_count[2], - map_count[3], map_folded_count[3], - mapping_unique, mapping_dupe); + "Statistics:\n" + "- width: %6u\n" + "- height: %6u\n" + "- glyph_total: %6u\n" + "- glyph_normal: %6u\n" + "- glyph_normal_right: %6u\n" + "- glyph_bold: %6u\n" + "- glyph_bold_right: %6u\n" + "- glyph_unique: %6u\n" + "- glyph_dupe: %6u\n" + "- mapping_total: %6u\n" + "- mapping_normal: %6u\n" + "- mapping_normal_folded: %6u\n" + "- mapping_normal_right: %6u\n" + "- mapping_normal_right_folded: %6u\n" + "- mapping_bold: %6u\n" + "- mapping_bold_folded: %6u\n" + "- mapping_bold_right: %6u\n" + "- mapping_bold_right_folded: %6u\n" + "- mapping_unique: %6u\n" + "- mapping_dupe: %6u\n", + width, height, + glyph_total, + glyph_count[0], + glyph_count[1], + glyph_count[2], + glyph_count[3], + glyph_unique, glyph_dupe, + mapping_total, + map_count[0], map_folded_count[0], + map_count[1], map_folded_count[1], + map_count[2], map_folded_count[2], + map_count[3], map_folded_count[3], + mapping_unique, mapping_dupe); } + int main(int argc, char *argv[]) { @@ -1044,14 +1172,15 @@ while ((ch = getopt(argc, argv, "nf:h:vw:o:")) != -1) { switch (ch) { case 'f': - if (strcmp(optarg, "font") == 0) + if (strcmp(optarg, "font") == 0) { format = VT_FONT; - else if (strcmp(optarg, "source") == 0) + } else if (strcmp(optarg, "source") == 0) { format = VT_C_SOURCE; - else if (strcmp(optarg, "compressed-source") == 0) + } else if (strcmp(optarg, "compressed-source") == 0) { format = VT_C_COMPRESSED; - else + } else { errx(1, "Invalid format: %s", optarg); + } break; case 'h': height = atoi(optarg); @@ -1076,8 +1205,9 @@ argc -= optind; argv += optind; - if (outfile == NULL && (argc < 2 || argc > 3)) + if ((outfile == NULL) && ((argc < 2) || (argc > 3))) { usage(); + } if (outfile == NULL) { outfile = argv[argc - 1]; @@ -1087,13 +1217,15 @@ set_width(width); set_height(height); - if (parse_file(argv[0], VFNT_MAP_NORMAL) != 0) + if (parse_file(argv[0], VFNT_MAP_NORMAL) != 0) { return (1); + } argc--; argv++; if (argc == 1) { - if (parse_file(argv[0], VFNT_MAP_BOLD) != 0) + if (parse_file(argv[0], VFNT_MAP_BOLD) != 0) { return (1); + } argc--; argv++; } @@ -1117,8 +1249,9 @@ break; } - if (verbose) + if (verbose) { print_font_info(); + } return (rv); }