summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authoremaste <emaste@FreeBSD.org>2014-06-05 18:38:27 +0000
committeremaste <emaste@FreeBSD.org>2014-06-05 18:38:27 +0000
commit2a36f1de847ef32c76c30118f4c3596fd3c84fed (patch)
tree3a9911147eb1630f2647a8fc5a909043dd90e0fb /tools
parent13fb8aa8937fba828538a1392258ad5afabb23dc (diff)
downloadFreeBSD-src-2a36f1de847ef32c76c30118f4c3596fd3c84fed.zip
FreeBSD-src-2a36f1de847ef32c76c30118f4c3596fd3c84fed.tar.gz
Support "GNU Unifont" format font data
The GNU Unifont .hex format is a text file. Each line represents one glyph and consists of a four-digit hex code point, a colon, and pairs of hex digits representing the bitmap. By default an 8x16 font is assumed, with 16x16 double-width glyphs, resulting in either 32 or 64 hex digits for the bitmap. Our version of the file format supports comments at the top of the file to set the height and width: # Height: <decimal height> # Width: <decimal width> Each row of bitmap data is rounded up to byte width - for example, a 10-pixel wide font uses 4 characters per row. See http://czyborra.com/unifont/ for more background on the original format. Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'tools')
-rw-r--r--tools/tools/vt/fontcvt/fontcvt.c114
1 files changed, 88 insertions, 26 deletions
diff --git a/tools/tools/vt/fontcvt/fontcvt.c b/tools/tools/vt/fontcvt/fontcvt.c
index 4e019cd..f4f5499 100644
--- a/tools/tools/vt/fontcvt/fontcvt.c
+++ b/tools/tools/vt/fontcvt/fontcvt.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2009 The FreeBSD Foundation
+ * Copyright (c) 2009, 2014 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Ed Schouten under sponsorship from the
@@ -179,6 +179,30 @@ add_glyph(const uint8_t *bytes, unsigned int map_idx, int fallback)
}
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)
{
@@ -218,20 +242,12 @@ parse_bitmap_line(uint8_t *left, uint8_t *right, unsigned int line,
}
static int
-parse_bdf(const char *filename, unsigned int map_idx)
+parse_bdf(FILE *fp, unsigned int map_idx)
{
- FILE *fp;
char *ln;
size_t length;
uint8_t bytes[wbytes * height], bytes_r[wbytes * height];
unsigned int curchar = 0, dwidth = 0, i, line;
- struct glyph *gl;
-
- fp = fopen(filename, "r");
- if (fp == NULL) {
- perror(filename);
- return (1);
- }
while ((ln = fgetln(fp, &length)) != NULL) {
ln[length - 1] = '\0';
@@ -257,27 +273,73 @@ parse_bdf(const char *filename, unsigned int map_idx)
return (1);
}
- /* 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)
+ 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 (dwidth == width * 2) {
- gl = add_glyph(bytes_r, map_idx + 1, 0);
- if (add_mapping(gl, curchar,
- map_idx + 1) != 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)
{
@@ -416,12 +478,12 @@ main(int argc, char *argv[])
wbytes = howmany(width, 8);
- if (parse_bdf(argv[0], VFNT_MAP_NORMAL) != 0)
+ if (parse_file(argv[0], VFNT_MAP_NORMAL) != 0)
return (1);
argc--;
argv++;
if (argc == 2) {
- if (parse_bdf(argv[0], VFNT_MAP_BOLD) != 0)
+ if (parse_file(argv[0], VFNT_MAP_BOLD) != 0)
return (1);
argc--;
argv++;
OpenPOWER on IntegriCloud