2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/pkg/landfall-examples/input_event_client/unifont.tff.needed Wed May 23 23:57:09 2018 +0200
2.3 @@ -0,0 +1,1 @@
2.4 +If unifont.tff is missing, generate it using the tools/makefonts.sh script.
3.1 --- a/tools/install.sh Mon May 21 00:52:45 2018 +0200
3.2 +++ b/tools/install.sh Wed May 23 23:57:09 2018 +0200
3.3 @@ -1,5 +1,10 @@
3.4 #!/bin/sh
3.5
3.6 +if ! which realpath > /dev/null ; then
3.7 + echo "Please install the realpath program." 1>&2
3.8 + exit 1
3.9 +fi
3.10 +
3.11 THISDIR=`dirname "$0"`
3.12 DIRNAME=`realpath "$THISDIR/.."`
3.13 PROGNAME=`basename "$0"`
3.14 @@ -40,7 +45,7 @@
3.15
3.16 L4DIR=$1
3.17
3.18 -# Copy (or remove) each of the objects.
3.19 +# Determine the mode.
3.20
3.21 if [ "$2" = '--clean' ] ; then
3.22 CLEAN=$2
3.23 @@ -48,6 +53,14 @@
3.24 CLEAN=
3.25 fi
3.26
3.27 +# Generate binaries if appropriate.
3.28 +
3.29 +if [ ! "$CLEAN" ] ; then
3.30 + "$THISDIR/makefonts.sh" -q
3.31 +fi
3.32 +
3.33 +# Copy (or remove) each of the objects.
3.34 +
3.35 for OBJTYPE in 'conf' 'pkg' ; do
3.36 TARGETDIR=`realpath "$L4DIR"`/$OBJTYPE
3.37 SOURCEDIR="$DIRNAME/$OBJTYPE"
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/tools/makefonts.sh Wed May 23 23:57:09 2018 +0200
4.3 @@ -0,0 +1,62 @@
4.4 +#!/bin/sh
4.5 +
4.6 +if ! which realpath > /dev/null ; then
4.7 + echo "Please install the realpath program." 1>&2
4.8 + exit 1
4.9 +fi
4.10 +
4.11 +THISDIR=`dirname "$0"`
4.12 +DIRNAME=`realpath "$THISDIR/.."`
4.13 +PROGNAME=`basename "$0"`
4.14 +
4.15 +UNIFONT='/usr/share/unifont/unifont.hex'
4.16 +
4.17 +if [ "$1" = '--help' ] ; then
4.18 + cat 1>&2 <<EOF
4.19 +Usage: $PROGNAME [ -q ]
4.20 +
4.21 +Find font usage and generate the necessary binary font files. Currently, only
4.22 +GNU Unifont is supported.
4.23 +
4.24 +The optional -q argument indicates quiet execution, suppressing all output.
4.25 +EOF
4.26 + exit 1
4.27 +fi
4.28 +
4.29 +# Detect quiet operation.
4.30 +
4.31 +if [ "$1" = '-q' ] ; then
4.32 + QUIET="$1"
4.33 + shift 1
4.34 +else
4.35 + QUIET=
4.36 +fi
4.37 +
4.38 +# Find all needed fonts and generate them.
4.39 +
4.40 +for NEEDED in `find "$DIRNAME/pkg" -name '*.tff.needed'` ; do
4.41 + TARGETDIR=`dirname "$NEEDED"`
4.42 + FONTFILE=`basename "$NEEDED" .needed`
4.43 + FONTNAME=`basename "$FONTFILE" .tff`
4.44 +
4.45 + FONTPATH="$TARGETDIR/$FONTFILE"
4.46 +
4.47 + if [ -e "$FONTPATH" ] ; then
4.48 + if [ ! "$QUIET" ] ; then
4.49 + echo "Exists, not generated: $FONTPATH" 1>&2
4.50 + fi
4.51 + continue
4.52 + fi
4.53 +
4.54 + if [ "$FONTNAME" != 'unifont' ] ; then
4.55 + if [ ! "$QUIET" ] ; then
4.56 + echo "Unrecognised ($FONTNAME), not generated: $FONTPATH" 1>&2
4.57 + fi
4.58 + continue
4.59 + fi
4.60 +
4.61 + if [ ! "$QUIET" ] ; then
4.62 + echo "$FONTPATH"
4.63 + fi
4.64 + "$THISDIR/readfont.py" "$UNIFONT" "$FONTPATH"
4.65 +done
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/tools/readfont.py Wed May 23 23:57:09 2018 +0200
5.3 @@ -0,0 +1,244 @@
5.4 +#!/usr/bin/env python
5.5 +
5.6 +"""
5.7 +Convert GNU Unifont format definitions into the .tff font format used by L4Re.
5.8 +Note that this .tff format is *not* .ttf, the latter being TrueType format.
5.9 +Searching the Internet for .tff will yield lots of .ttf nonsense.
5.10 +
5.11 +Copyright (C) 2017, 2018 Paul Boddie <paul@boddie.org.uk>
5.12 +
5.13 +This program is free software; you can redistribute it and/or modify it under
5.14 +the terms of the GNU General Public License as published by the Free Software
5.15 +Foundation; either version 3 of the License, or (at your option) any later
5.16 +version.
5.17 +
5.18 +This program is distributed in the hope that it will be useful, but WITHOUT ANY
5.19 +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
5.20 +PARTICULAR PURPOSE. See the GNU General Public License for more details.
5.21 +
5.22 +You should have received a copy of the GNU General Public License along
5.23 +with this program. If not, see <http://www.gnu.org/licenses/>.
5.24 +"""
5.25 +
5.26 +from os.path import split
5.27 +import sys
5.28 +
5.29 +def convert_font(fin, fout, points, missing=32):
5.30 +
5.31 + """
5.32 + Convert the font obtained via 'fin' to an assembly language representation,
5.33 + writing to 'fout' the characters for the chosen sequence of 'points'.
5.34 +
5.35 + A table of offsets is written to permit each character to be found in the
5.36 + generated data.
5.37 +
5.38 + If 'missing' is specified, the character of the given value will be used
5.39 + for missing character data.
5.40 + """
5.41 +
5.42 + points.sort()
5.43 + base = points[0]
5.44 + limit = points[-1]
5.45 +
5.46 + # Store the offset of each chosen character.
5.47 +
5.48 + table = []
5.49 +
5.50 + # Search for each character until no more remain to be found.
5.51 +
5.52 + index = 0
5.53 + end = len(points)
5.54 +
5.55 + # Record character widths and bitmaps.
5.56 +
5.57 + widths = []
5.58 + bitmaps = []
5.59 + height = 16
5.60 +
5.61 + line = fin.readline()
5.62 +
5.63 + while line and index < end:
5.64 + point, width, bytes = read_entry(line, height)
5.65 +
5.66 + # Add a null offset for unselected characters.
5.67 +
5.68 + if point < points[index]:
5.69 + if point >= base:
5.70 + widths.append(None)
5.71 + bitmaps.append(None)
5.72 + line = fin.readline()
5.73 + continue
5.74 +
5.75 + bitmaps.append(bytes)
5.76 + widths.append(width)
5.77 +
5.78 + index += 1
5.79 + line = fin.readline()
5.80 +
5.81 + # Generate the offsets.
5.82 +
5.83 + line_step = 0
5.84 +
5.85 + for width in widths:
5.86 + if width is None:
5.87 + width = widths[missing - base]
5.88 + table.append(line_step)
5.89 + line_step += width
5.90 +
5.91 + # Write the offset table.
5.92 +
5.93 + for offset in table:
5.94 + if offset is None:
5.95 + offset = table[missing - base]
5.96 + fout.write(uint32_out(offset))
5.97 +
5.98 + # Write the widths table.
5.99 +
5.100 + for width in widths:
5.101 + if width is None:
5.102 + width = widths[missing - base]
5.103 + fout.write(uint32_out(width))
5.104 +
5.105 + # Write the line data step size and common height.
5.106 +
5.107 + fout.write(uint32_out(line_step))
5.108 + fout.write(uint32_out(height))
5.109 +
5.110 + # Write the bitmaps.
5.111 +
5.112 + line = 0
5.113 + while line < height:
5.114 + for width, bitmap in zip(widths, bitmaps):
5.115 + if bitmap is None:
5.116 + bitmap = bitmaps[missing - base]
5.117 +
5.118 + bytes_per_line = width / 8
5.119 + start = line * bytes_per_line
5.120 +
5.121 + data = bitmap[start:start+bytes_per_line]
5.122 + fout.write(bits_out(data))
5.123 +
5.124 + line += 1
5.125 +
5.126 +def read_entry(line, height):
5.127 +
5.128 + # Obtain the code point and data.
5.129 +
5.130 + point, data = line.rstrip().split(":")
5.131 + point = int(point, 16)
5.132 +
5.133 + # Each data digit represents four bits.
5.134 +
5.135 + width = (len(data) * 4) / height
5.136 +
5.137 + # Obtain the byte values from the data.
5.138 +
5.139 + bytes = []
5.140 + i = 0
5.141 + while i < len(data):
5.142 + bytes.append(int(data[i:i+2], 16))
5.143 + i += 2
5.144 +
5.145 + return point, width, bytes
5.146 +
5.147 +# Utilities for writing .tff fonts.
5.148 +
5.149 +def bits_out(s):
5.150 + result = []
5.151 + for value in s[::-1]:
5.152 + i = 0
5.153 + while i < 8:
5.154 + result.insert(0, (value & 0x01) and "\xff" or "\x00")
5.155 + value >>= 1
5.156 + i += 1
5.157 + return "".join(result)
5.158 +
5.159 +def uint32_out(value):
5.160 + result = []
5.161 + i = 0
5.162 + while i < 4:
5.163 + result.append(chr(value & 0xff))
5.164 + value >>= 8
5.165 + i += 1
5.166 + return "".join(result)
5.167 +
5.168 +# Utilities for reading .tff fonts.
5.169 +
5.170 +def uint32(s):
5.171 + result = 0
5.172 + i = 3
5.173 + while i >= 0:
5.174 + result = (result << 8) + ord(s[i])
5.175 + i -= 1
5.176 + return result
5.177 +
5.178 +def words(s):
5.179 + l = []
5.180 + i = 0
5.181 + while i < len(s):
5.182 + l.append(s[i:i+4])
5.183 + i += 4
5.184 + return l
5.185 +
5.186 +class Font:
5.187 +
5.188 + "An abstraction for the .tff format."
5.189 +
5.190 + def __init__(self, filename):
5.191 + f = open(filename)
5.192 + try:
5.193 + self.otab = map(uint32, words(f.read(1024)))
5.194 + self.wtab = map(uint32, words(f.read(1024)))
5.195 + self.w = uint32(f.read(4))
5.196 + self.h = uint32(f.read(4))
5.197 + self.img = f.read()
5.198 + finally:
5.199 + f.close()
5.200 +
5.201 + def show(self, c):
5.202 + num = ord(c)
5.203 + offset = self.otab[num]
5.204 + row = 0
5.205 + while row < self.h:
5.206 + start = offset + row * self.w
5.207 + print self.img[start:start + self.wtab[num]].replace("\xff", "#").replace("\x00", ".")
5.208 + row += 1
5.209 +
5.210 +# Main program.
5.211 +
5.212 +if __name__ == "__main__":
5.213 +
5.214 + # Test options.
5.215 +
5.216 + if "--help" in sys.argv or len(sys.argv) < 3:
5.217 + basename = split(sys.argv[0])[1]
5.218 + print >>sys.stderr, """\
5.219 +Usage:
5.220 +
5.221 +%s <input filename> <output filename>
5.222 +""" % basename
5.223 + sys.exit(1)
5.224 +
5.225 + base = 0
5.226 + points = range(base, 256)
5.227 +
5.228 + filename_or_option, tff_filename = sys.argv[1:3]
5.229 +
5.230 + if filename_or_option == "--show":
5.231 + f = Font(tff_filename)
5.232 + for arg in sys.argv[3:]:
5.233 + for char in arg:
5.234 + f.show(char)
5.235 +
5.236 + # Convert from the input to the output file.
5.237 +
5.238 + else:
5.239 + fin = open(filename_or_option)
5.240 + fout = open(tff_filename, "w")
5.241 + try:
5.242 + convert_font(fin, fout, points, base)
5.243 + finally:
5.244 + fin.close()
5.245 + fout.close()
5.246 +
5.247 +# vim: tabstop=4 expandtab shiftwidth=4