aboutsummaryrefslogtreecommitdiff
path: root/console-tools/loadfont.c
diff options
context:
space:
mode:
authorGravatar Denis Vlasenko <vda.linux@googlemail.com>2008-08-17 14:12:26 +0000
committerGravatar Denis Vlasenko <vda.linux@googlemail.com>2008-08-17 14:12:26 +0000
commitc8d02aa959d3543239701d7170e0255c49ad6d9e (patch)
treedff730a0992022105fa3b2795edc1af5055dbc80 /console-tools/loadfont.c
parenteb084779d7f3feba414d679006d4f1633451677f (diff)
downloadbusybox-c8d02aa959d3543239701d7170e0255c49ad6d9e.tar.gz
busybox-c8d02aa959d3543239701d7170e0255c49ad6d9e.tar.bz2
setfont: new applet by Vladimir
Diffstat (limited to 'console-tools/loadfont.c')
-rw-r--r--console-tools/loadfont.c140
1 files changed, 78 insertions, 62 deletions
diff --git a/console-tools/loadfont.c b/console-tools/loadfont.c
index 567aa38ae..78700706f 100644
--- a/console-tools/loadfont.c
+++ b/console-tools/loadfont.c
@@ -26,7 +26,7 @@ struct psf_header {
unsigned char charsize; /* Character size */
};
-#define PSF_MAGIC_OK(x) ((x).magic1 == PSF_MAGIC1 && (x).magic2 == PSF_MAGIC2)
+#define PSF_MAGIC_OK(x) ((x)->magic1 == PSF_MAGIC1 && (x)->magic2 == PSF_MAGIC2)
static void do_loadfont(int fd, unsigned char *inbuf, int unit, int fontsize)
{
@@ -37,7 +37,6 @@ static void do_loadfont(int fd, unsigned char *inbuf, int unit, int fontsize)
bb_error_msg_and_die("bad character size %d", unit);
buf = xzalloc(16 * 1024);
- /*memset(buf, 0, 16 * 1024);*/
for (i = 0; i < fontsize; i++)
memcpy(buf + (32 * i), inbuf + (unit * i), unit);
@@ -58,8 +57,7 @@ static void do_loadfont(int fd, unsigned char *inbuf, int unit, int fontsize)
free(buf);
}
-static void
-do_loadtable(int fd, unsigned char *inbuf, int tailsz, int fontsize)
+static void do_loadtable(int fd, unsigned char *inbuf, int tailsz, int fontsize)
{
struct unimapinit advice;
struct unimapdesc ud;
@@ -68,7 +66,7 @@ do_loadtable(int fd, unsigned char *inbuf, int tailsz, int fontsize)
int glyph;
uint16_t unicode;
- maxct = tailsz; /* more than enough */
+ maxct = tailsz; /* more than enough */
up = xmalloc(maxct * sizeof(struct unipair));
for (glyph = 0; glyph < fontsize; glyph++) {
@@ -96,86 +94,104 @@ do_loadtable(int fd, unsigned char *inbuf, int tailsz, int fontsize)
xioctl(fd, PIO_UNIMAP, &ud);
}
-static void loadnewfont(int fd)
+static void do_load(int fd, struct psf_header *psfhdr, size_t len)
{
- enum { INBUF_SIZE = 32*1024 + 1 };
-
int unit;
- unsigned inputlth, offset;
- /* Was on stack, but 32k is a bit too much: */
- unsigned char *inbuf = xmalloc(INBUF_SIZE);
-
- /*
- * We used to look at the length of the input file
- * with stat(); now that we accept compressed files,
- * just read the entire file.
- */
- inputlth = full_read(STDIN_FILENO, inbuf, INBUF_SIZE);
- if (inputlth < 0)
- bb_perror_msg_and_die("error reading input font");
- if (inputlth >= INBUF_SIZE)
- bb_error_msg_and_die("font too large");
+ int fontsize;
+ int hastable;
+ unsigned head0, head = head;
/* test for psf first */
- {
- struct psf_header psfhdr;
- int fontsize;
- int hastable;
- unsigned head0, head;
-
- if (inputlth < sizeof(struct psf_header))
- goto no_psf;
-
- psfhdr = *(struct psf_header *) &inbuf[0];
-
- if (!PSF_MAGIC_OK(psfhdr))
- goto no_psf;
-
- if (psfhdr.mode > PSF_MAXMODE)
+ if (len >= sizeof(struct psf_header) && PSF_MAGIC_OK(psfhdr)) {
+ if (psfhdr->mode > PSF_MAXMODE)
bb_error_msg_and_die("unsupported psf file mode");
- fontsize = ((psfhdr.mode & PSF_MODE512) ? 512 : 256);
+ fontsize = ((psfhdr->mode & PSF_MODE512) ? 512 : 256);
#if !defined(PIO_FONTX) || defined(__sparc__)
if (fontsize != 256)
bb_error_msg_and_die("only fontsize 256 supported");
#endif
- hastable = (psfhdr.mode & PSF_MODEHASTAB);
- unit = psfhdr.charsize;
+ hastable = (psfhdr->mode & PSF_MODEHASTAB);
+ unit = psfhdr->charsize;
head0 = sizeof(struct psf_header);
head = head0 + fontsize * unit;
- if (head > inputlth || (!hastable && head != inputlth))
+ if (head > len || (!hastable && head != len))
bb_error_msg_and_die("input file: bad length");
- do_loadfont(fd, inbuf + head0, unit, fontsize);
- if (hastable)
- do_loadtable(fd, inbuf + head, inputlth - head, fontsize);
- return;
- }
-
- no_psf:
- /* file with three code pages? */
- if (inputlth == 9780) {
- offset = 40;
- unit = 16;
} else {
- /* bare font */
- if (inputlth & 0377)
- bb_error_msg_and_die("bad input file size");
- offset = 0;
- unit = inputlth / 256;
+ /* file with three code pages? */
+ if (len == 9780) {
+ head0 = 40;
+ unit = 16;
+ } else {
+ /* bare font */
+ if (len & 0377)
+ bb_error_msg_and_die("input file: bad length");
+ head0 = 0;
+ unit = len / 256;
+ }
+ fontsize = 256;
+ hastable = 0;
}
- do_loadfont(fd, inbuf + offset, unit, 256);
+
+ do_loadfont(fd, (unsigned char *)psfhdr + head0, unit, fontsize);
+ if (hastable)
+ do_loadtable(fd, (unsigned char *)psfhdr + head, len - head, fontsize);
}
+#if ENABLE_LOADFONT
int loadfont_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
-int loadfont_main(int argc, char **argv UNUSED_PARAM)
+int loadfont_main(int argc UNUSED_PARAM, char **argv)
{
+ size_t len;
+ struct psf_header *psfhdr;
+
+ // no arguments allowed!
+ opt_complementary = "=0";
+ getopt32(argv, "");
+
+ /*
+ * We used to look at the length of the input file
+ * with stat(); now that we accept compressed files,
+ * just read the entire file.
+ */
+ len = 32*1024; // can't be larger
+ psfhdr = (struct psf_header *) xmalloc_read(STDIN_FILENO, &len);
+ // xmalloc_open_zipped_read_close(filename, &len);
+ if (!psfhdr)
+ bb_perror_msg_and_die("error reading input font");
+ do_load(get_console_fd_or_die(), psfhdr, len);
+
+ return EXIT_SUCCESS;
+}
+#endif
+
+#if ENABLE_SETFONT
+int setfont_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int setfont_main(int argc UNUSED_PARAM, char **argv)
+{
+ size_t len;
+ struct psf_header *psfhdr;
+ char *mapfilename;
int fd;
- if (argc != 1)
- bb_show_usage();
+ opt_complementary = "=1";
+ getopt32(argv, "m:", &mapfilename);
+ argv += optind;
+ // load font
+ len = 32*1024; // can't be larger
+ psfhdr = (struct psf_header *) xmalloc_open_zipped_read_close(*argv, &len);
fd = get_console_fd_or_die();
- loadnewfont(fd);
+ do_load(fd, psfhdr, len);
+
+ // load the screen map, if any
+ if (option_mask32 & 1) { // -m
+ void *map = xmalloc_open_zipped_read_close(mapfilename, &len);
+ if (len == E_TABSZ || len == 2*E_TABSZ) {
+ xioctl(fd, (len == 2*E_TABSZ) ? PIO_UNISCRNMAP : PIO_SCRNMAP, map);
+ }
+ }
return EXIT_SUCCESS;
}
+#endif