summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authoremaste <emaste@FreeBSD.org>2014-06-10 18:29:45 +0000
committeremaste <emaste@FreeBSD.org>2014-06-10 18:29:45 +0000
commitef4a53af9d0e827750d732318f73b502b1ac8112 (patch)
treec816dcd4c879034ec3cc2050c1c2573852639eb1 /tools
parent7ed71b98ff7a68f3dc2ef5ca46dff87c3b11edf7 (diff)
downloadFreeBSD-src-ef4a53af9d0e827750d732318f73b502b1ac8112.zip
FreeBSD-src-ef4a53af9d0e827750d732318f73b502b1ac8112.tar.gz
vt fontcvt: move to usr.bin/vtfontcvt
vtfontcvt is useful for end users to convert arbitrary bitmap fonts for use by vt(4). It can also be used as a build tool, allowing us to keep the source font data in the src tree rather than uuencoded binaries. Reviewed by: ray, wblock (D183) Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'tools')
-rw-r--r--tools/tools/vt/fontcvt/Makefile6
-rw-r--r--tools/tools/vt/fontcvt/fontcvt.c568
-rw-r--r--tools/tools/vt/fontcvt/terminus.sh2
3 files changed, 1 insertions, 575 deletions
diff --git a/tools/tools/vt/fontcvt/Makefile b/tools/tools/vt/fontcvt/Makefile
deleted file mode 100644
index 06692d0..0000000
--- a/tools/tools/vt/fontcvt/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-PROG= fontcvt
-MAN1=
-
-WARNS?= 6
-
-.include <bsd.prog.mk>
diff --git a/tools/tools/vt/fontcvt/fontcvt.c b/tools/tools/vt/fontcvt/fontcvt.c
deleted file mode 100644
index 5acad70..0000000
--- a/tools/tools/vt/fontcvt/fontcvt.c
+++ /dev/null
@@ -1,568 +0,0 @@
-/*-
- * Copyright (c) 2009, 2014 The FreeBSD Foundation
- * All rights reserved.
- *
- * This software was developed by Ed Schouten under sponsorship from the
- * FreeBSD Foundation.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/types.h>
-#include <sys/fnv_hash.h>
-#include <sys/endian.h>
-#include <sys/param.h>
-#include <sys/queue.h>
-
-#include <assert.h>
-#include <err.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define VFNT_MAPS 4
-#define VFNT_MAP_NORMAL 0
-#define VFNT_MAP_NORMAL_RH 1
-#define VFNT_MAP_BOLD 2
-#define VFNT_MAP_BOLD_RH 3
-
-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;
-};
-
-#define FONTCVT_NHASH 4096
-TAILQ_HEAD(glyph_list, glyph);
-static SLIST_HEAD(, glyph) glyph_hash[FONTCVT_NHASH];
-static struct glyph_list glyphs[VFNT_MAPS] = {
- TAILQ_HEAD_INITIALIZER(glyphs[0]),
- TAILQ_HEAD_INITIALIZER(glyphs[1]),
- TAILQ_HEAD_INITIALIZER(glyphs[2]),
- TAILQ_HEAD_INITIALIZER(glyphs[3]),
-};
-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_HEAD(mapping_list, mapping);
-static struct mapping_list maps[VFNT_MAPS] = {
- TAILQ_HEAD_INITIALIZER(maps[0]),
- TAILQ_HEAD_INITIALIZER(maps[1]),
- TAILQ_HEAD_INITIALIZER(maps[2]),
- TAILQ_HEAD_INITIALIZER(maps[3]),
-};
-static unsigned int mapping_total, map_count[4], map_folded_count[4],
- mapping_unique, mapping_dupe;
-
-static void
-usage(void)
-{
-
- errx(1,
-"usage: fontcvt [-w width] [-h height] [-v] normal.bdf [bold.bdf] out.fnt\n");
- exit(1);
-}
-
-static int
-add_mapping(struct glyph *gl, unsigned int c, unsigned int map_idx)
-{
- struct mapping *mp;
- struct mapping_list *ml;
-
- mapping_total++;
-
- mp = malloc(sizeof *mp);
- mp->m_char = c;
- mp->m_glyph = gl;
- mp->m_length = 0;
-
- ml = &maps[map_idx];
- if (TAILQ_LAST(ml, mapping_list) != NULL &&
- TAILQ_LAST(ml, mapping_list)->m_char >= c) {
- errx(1, "Bad ordering at character %u\n", c);
- return (1);
- }
- TAILQ_INSERT_TAIL(ml, mp, m_list);
-
- map_count[map_idx]++;
- mapping_unique++;
-
- return (0);
-}
-
-static int
-dedup_mapping(unsigned int map_idx)
-{
- struct mapping *mp_bold, *mp_normal, *mp_temp;
- unsigned normal_map_idx = map_idx - VFNT_MAP_BOLD;
-
- assert(map_idx == VFNT_MAP_BOLD || map_idx == VFNT_MAP_BOLD_RH);
- 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)
- mp_normal = TAILQ_NEXT(mp_normal, m_list);
- if (mp_bold->m_char != mp_normal->m_char) {
- errx(1, "Character %u not in normal font!\n",
- mp_bold->m_char);
- return (1);
- }
- 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);
- free(mp_bold);
- mapping_dupe++;
- }
- return (0);
-}
-
-static struct glyph *
-add_glyph(const uint8_t *bytes, unsigned int map_idx, int fallback)
-{
- struct glyph *gl;
- int hash;
-
- glyph_total++;
- glyph_count[map_idx]++;
-
- hash = fnv_32_buf(bytes, wbytes * height, FNV1_32_INIT) % FONTCVT_NHASH;
- SLIST_FOREACH(gl, &glyph_hash[hash], g_hash) {
- if (memcmp(gl->g_data, bytes, wbytes * height) == 0) {
- glyph_dupe++;
- return (gl);
- }
- }
-
- gl = malloc(sizeof *gl);
- gl->g_data = malloc(wbytes * height);
- memcpy(gl->g_data, bytes, wbytes * height);
- if (fallback)
- TAILQ_INSERT_HEAD(&glyphs[map_idx], gl, g_list);
- else
- TAILQ_INSERT_TAIL(&glyphs[map_idx], gl, g_list);
- SLIST_INSERT_HEAD(&glyph_hash[hash], gl, g_hash);
-
- glyph_unique++;
- return (gl);
-}
-
-static int
-add_char(unsigned curchar, unsigned map_idx, uint8_t *bytes, uint8_t *bytes_r)
-{
- struct glyph *gl;
-
- /* Prevent adding two glyphs for 0xFFFD */
- if (curchar == 0xFFFD) {
- if (map_idx < VFNT_MAP_BOLD)
- gl = add_glyph(bytes, 0, 1);
- } else if (curchar >= 0x20) {
- gl = add_glyph(bytes, 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)
- return (1);
- }
- }
- return (0);
-}
-
-
-static int
-parse_bitmap_line(uint8_t *left, uint8_t *right, unsigned int line,
- unsigned int dwidth)
-{
- uint8_t *p;
- unsigned int i, subline;
-
- if (dwidth != width && dwidth != width * 2) {
- errx(1,
- "Bitmap with unsupported width %u!\n", dwidth);
- return (1);
- }
-
- /* Move pixel data right to simplify splitting double characters. */
- line >>= (howmany(dwidth, 8) * 8) - dwidth;
-
- for (i = dwidth / width; i > 0; i--) {
- p = (i == 2) ? right : left;
-
- subline = line & ((1 << width) - 1);
- subline <<= (howmany(width, 8) * 8) - width;
-
- if (wbytes == 1) {
- *p = subline;
- } else if (wbytes == 2) {
- *p++ = subline >> 8;
- *p = subline;
- } else {
- errx(1,
- "Unsupported wbytes %u!\n", wbytes);
- return (1);
- }
-
- line >>= width;
- }
-
- return (0);
-}
-
-static int
-parse_bdf(FILE *fp, unsigned int map_idx)
-{
- char *ln;
- size_t length;
- uint8_t bytes[wbytes * height], bytes_r[wbytes * height];
- unsigned int curchar = 0, dwidth = 0, i, line;
-
- while ((ln = fgetln(fp, &length)) != NULL) {
- ln[length - 1] = '\0';
-
- if (strncmp(ln, "ENCODING ", 9) == 0) {
- curchar = atoi(ln + 9);
- }
-
- if (strncmp(ln, "DWIDTH ", 7) == 0) {
- dwidth = atoi(ln + 7);
- }
-
- if (strncmp(ln, "BITMAP", 6) == 0 &&
- (ln[6] == ' ' || ln[6] == '\0')) {
- for (i = 0; i < height; i++) {
- if ((ln = fgetln(fp, &length)) == NULL) {
- errx(1, "Unexpected EOF!\n");
- return (1);
- }
- ln[length - 1] = '\0';
- sscanf(ln, "%x", &line);
- if (parse_bitmap_line(bytes + i * wbytes,
- bytes_r + i * wbytes, line, dwidth) != 0)
- return (1);
- }
-
- if (add_char(curchar, map_idx, bytes,
- dwidth == width * 2 ? bytes_r : NULL) != 0)
- return (1);
- }
- }
-
- return (0);
-}
-
-static int
-parse_hex(FILE *fp, unsigned int map_idx)
-{
- char *ln, *p;
- char fmt_str[8];
- size_t length;
- uint8_t bytes[wbytes * height], bytes_r[wbytes * height];
- unsigned curchar = 0, i, line, chars_per_row, dwidth;
-
- while ((ln = fgetln(fp, &length)) != NULL) {
- ln[length - 1] = '\0';
-
- if (strncmp(ln, "# Height: ", 10) == 0) {
- height = atoi(ln + 10);
- } else if (strncmp(ln, "# Width: ", 9) == 0) {
- width = atoi(ln + 9);
- } else if (sscanf(ln, "%4x:", &curchar)) {
- p = ln + 5;
- chars_per_row = strlen(p) / height;
- dwidth = width;
- if (chars_per_row / 2 > width / 8)
- dwidth *= 2; /* Double-width character. */
- snprintf(fmt_str, sizeof(fmt_str), "%%%ux",
- chars_per_row);
-
- for (i = 0; i < height; i++) {
- sscanf(p, fmt_str, &line);
- p += chars_per_row;
- if (parse_bitmap_line(bytes + i * wbytes,
- bytes_r + i * wbytes, line, dwidth) != 0)
- return (1);
- }
-
- if (add_char(curchar, map_idx, bytes,
- dwidth == width * 2 ? bytes_r : NULL) != 0)
- return (1);
- }
- }
- return (0);
-}
-
-static int
-parse_file(const char *filename, unsigned int map_idx)
-{
- FILE *fp;
- size_t len;
-
- fp = fopen(filename, "r");
- if (fp == NULL) {
- perror(filename);
- return (1);
- }
- len = strlen(filename);
- if (len > 4 && strcasecmp(filename + len - 4, ".hex") == 0)
- return parse_hex(fp, map_idx);
- return parse_bdf(fp, map_idx);
-}
-
-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)
- gl->g_index = idx++;
-}
-
-static int
-write_glyphs(FILE *fp)
-{
- struct glyph *gl;
- unsigned int i;
-
- for (i = 0; i < VFNT_MAPS; i++) {
- TAILQ_FOREACH(gl, &glyphs[i], g_list)
- if (fwrite(gl->g_data, wbytes * height, 1, fp) != 1)
- return (1);
- }
- return (0);
-}
-
-static void
-fold_mappings(unsigned int map_idx)
-{
- struct mapping_list *ml = &maps[map_idx];
- struct mapping *mn, *mp, *mbase;
-
- 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)
- continue;
- mbase->m_length = mp->m_char - mbase->m_char + 1;
- mbase = mp = mn;
- map_folded_count[map_idx]++;
- }
-}
-
-struct file_mapping {
- uint32_t source;
- uint16_t destination;
- uint16_t length;
-} __packed;
-
-static int
-write_mappings(FILE *fp, unsigned int map_idx)
-{
- struct mapping_list *ml = &maps[map_idx];
- struct mapping *mp;
- struct file_mapping fm;
- unsigned int i = 0, j = 0;
-
- TAILQ_FOREACH(mp, ml, m_list) {
- j++;
- if (mp->m_length > 0) {
- i += mp->m_length;
- fm.source = htobe32(mp->m_char);
- fm.destination = htobe16(mp->m_glyph->g_index);
- fm.length = htobe16(mp->m_length - 1);
- if (fwrite(&fm, sizeof fm, 1, fp) != 1)
- return (1);
- }
- }
- assert(i == j);
- return (0);
-}
-
-struct file_header {
- uint8_t magic[8];
- uint8_t width;
- uint8_t height;
- uint16_t pad;
- uint32_t glyph_count;
- uint32_t map_count[4];
-} __packed;
-
-static int
-write_fnt(const char *filename)
-{
- FILE *fp;
- struct file_header fh = {
- .magic = "VFNT0002",
- };
-
- fp = fopen(filename, "wb");
- if (fp == NULL) {
- perror(filename);
- return (1);
- }
-
- fh.width = width;
- fh.height = height;
- fh.glyph_count = htobe32(glyph_unique);
- fh.map_count[0] = htobe32(map_folded_count[0]);
- fh.map_count[1] = htobe32(map_folded_count[1]);
- fh.map_count[2] = htobe32(map_folded_count[2]);
- fh.map_count[3] = htobe32(map_folded_count[3]);
- if (fwrite(&fh, sizeof fh, 1, fp) != 1) {
- perror(filename);
- return (1);
- }
-
- if (write_glyphs(fp) != 0 ||
- write_mappings(fp, VFNT_MAP_NORMAL) != 0 ||
- write_mappings(fp, 1) != 0 ||
- write_mappings(fp, VFNT_MAP_BOLD) != 0 ||
- write_mappings(fp, 3) != 0) {
- perror(filename);
- return (1);
- }
-
- return (0);
-}
-
-static void
-print_font_info(void)
-{
- printf(
-"Statistics:\n"
-"- glyph_total: %5u\n"
-"- glyph_normal: %5u\n"
-"- glyph_normal_right: %5u\n"
-"- glyph_bold: %5u\n"
-"- glyph_bold_right: %5u\n"
-"- glyph_unique: %5u\n"
-"- glyph_dupe: %5u\n"
-"- mapping_total: %5u\n"
-"- mapping_normal: %5u\n"
-"- mapping_normal_folded: %5u\n"
-"- mapping_normal_right: %5u\n"
-"- mapping_normal_right_folded: %5u\n"
-"- mapping_bold: %5u\n"
-"- mapping_bold_folded: %5u\n"
-"- mapping_bold_right: %5u\n"
-"- mapping_bold_right_folded: %5u\n"
-"- mapping_unique: %5u\n"
-"- mapping_dupe: %5u\n",
- 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[])
-{
- int ch, val, verbose = 0;
-
- assert(sizeof(struct file_header) == 32);
- assert(sizeof(struct file_mapping) == 8);
-
- while ((ch = getopt(argc, argv, "h:w:")) != -1) {
- switch (ch) {
- case 'h':
- val = atoi(optarg);
- if (val <= 0 || val > 128) {
- errx(1, "Invalid height %d", val);
- return (1);
- }
- height = val;
- break;
- case 'v':
- verbose = 1;
- break;
- case 'w':
- val = atoi(optarg);
- if (val <= 0 || val > 128) {
- errx(1, "Invalid width %d", val);
- return (1);
- }
- width = val;
- break;
- case '?':
- default:
- usage();
- }
- }
- argc -= optind;
- argv += optind;
-
- if (argc < 2 || argc > 3)
- usage();
-
- wbytes = howmany(width, 8);
-
- if (parse_file(argv[0], VFNT_MAP_NORMAL) != 0)
- return (1);
- argc--;
- argv++;
- if (argc == 2) {
- if (parse_file(argv[0], VFNT_MAP_BOLD) != 0)
- return (1);
- argc--;
- argv++;
- }
- number_glyphs();
- dedup_mapping(VFNT_MAP_BOLD);
- dedup_mapping(VFNT_MAP_BOLD_RH);
- fold_mappings(0);
- fold_mappings(1);
- fold_mappings(2);
- fold_mappings(3);
- if (write_fnt(argv[0]) != 0)
- return (1);
-
- if (verbose)
- print_font_info();
-
- return (0);
-}
diff --git a/tools/tools/vt/fontcvt/terminus.sh b/tools/tools/vt/fontcvt/terminus.sh
index b04c100..d186e3e 100644
--- a/tools/tools/vt/fontcvt/terminus.sh
+++ b/tools/tools/vt/fontcvt/terminus.sh
@@ -5,7 +5,7 @@ for i in 6:12 8:14 8:16 10:18 10:20 11:22 12:24 14:28 16:32
do
C=`echo $i | cut -f 1 -d :`
R=`echo $i | cut -f 2 -d :`
- ./fontcvt \
+ ./vtfontcvt \
-w $C -h $R \
~/terminus-font-4.36/ter-u${R}n.bdf \
~/terminus-font-4.36/ter-u${R}b.bdf \
OpenPOWER on IntegriCloud