From owner-svn-src-all@FreeBSD.ORG Thu Jun 5 18:38:28 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 929EFC6A; Thu, 5 Jun 2014 18:38:28 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 739BD2CC7; Thu, 5 Jun 2014 18:38:28 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s55IcS4o014711; Thu, 5 Jun 2014 18:38:28 GMT (envelope-from emaste@svn.freebsd.org) Received: (from emaste@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s55IcSJT014710; Thu, 5 Jun 2014 18:38:28 GMT (envelope-from emaste@svn.freebsd.org) Message-Id: <201406051838.s55IcSJT014710@svn.freebsd.org> From: Ed Maste Date: Thu, 5 Jun 2014 18:38:28 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r267123 - head/tools/tools/vt/fontcvt X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 Jun 2014 18:38:28 -0000 Author: emaste Date: Thu Jun 5 18:38:27 2014 New Revision: 267123 URL: http://svnweb.freebsd.org/changeset/base/267123 Log: 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: # 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 Modified: head/tools/tools/vt/fontcvt/fontcvt.c Modified: head/tools/tools/vt/fontcvt/fontcvt.c ============================================================================== --- head/tools/tools/vt/fontcvt/fontcvt.c Thu Jun 5 18:23:51 2014 (r267122) +++ head/tools/tools/vt/fontcvt/fontcvt.c Thu Jun 5 18:38:27 2014 (r267123) @@ -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 } 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 } 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 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++;