Module Name: xsrc
Committed By: macallan
Date: Mon Jan 8 18:09:33 UTC 2024
Modified Files:
xsrc/local/programs/bdfload: bdfload.c
Log Message:
add support for doubling a font's size, with optional smoothing
- works only on fonts up to 8 pixels wide for now
- smoothing attempts to detect pixel staircases and add pixels to smooth
them out
To generate a diff of this commit:
cvs rdiff -u -r1.20 -r1.21 xsrc/local/programs/bdfload/bdfload.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: xsrc/local/programs/bdfload/bdfload.c
diff -u xsrc/local/programs/bdfload/bdfload.c:1.20 xsrc/local/programs/bdfload/bdfload.c:1.21
--- xsrc/local/programs/bdfload/bdfload.c:1.20 Thu Jul 27 08:44:42 2023
+++ xsrc/local/programs/bdfload/bdfload.c Mon Jan 8 18:09:33 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: bdfload.c,v 1.20 2023/07/27 08:44:42 macallan Exp $ */
+/* $NetBSD: bdfload.c,v 1.21 2024/01/08 18:09:33 macallan Exp $ */
/*
* Copyright (c) 2018 Michael Lorenz
@@ -103,6 +103,8 @@ int verbose = 0;
int dump = 0;
int header = 0;
int force = 0;
+int scale = 0;
+int smoothe = 0;
char commentbuf[2048] = "";
int commentptr = 0;
char fontname[64] = "";
@@ -125,9 +127,11 @@ dump_line(char *gptr, int stride)
}
void
-write_wsf(const char *oname, struct wsdisplay_font *f, char *buffer, int buflen)
+write_wsf(const char *oname, struct wsdisplay_font *f)
{
struct wsfthdr h;
+ uint8_t *buffer = f->data;
+ int buflen = f->numchars * f->stride * f->fontheight;
memset(&h, 0, sizeof(h));
strncpy(h.magic, "WSFT", sizeof(h.magic));
@@ -161,10 +165,10 @@ write_wsf(const char *oname, struct wsdi
}
int
-write_header(const char *filename, struct wsdisplay_font *f,
- char *buffer, int buflen)
+write_header(const char *filename, struct wsdisplay_font *f)
{
FILE *output;
+ char *buffer = f->data;
int i, j, x, y, idx, pxls, left;
char name[64], c, msk;
@@ -200,11 +204,11 @@ write_header(const char *filename, struc
fprintf(output, "\t%s_data\t\t/* data */\n", name);
fprintf(output, "};\n\n");
fprintf(output, "static u_char %s_data[] = {\n", name);
- for (i = f->firstchar; i < f->firstchar + f->numchars; i++) {
+ for (i = 0; i < f->numchars; i++) {
if (names[i] != NULL) {
- fprintf(output, "\t/* %d %s */\n", i, names[i]);
+ fprintf(output, "\t/* %d %s */\n", i + f->firstchar, names[i]);
} else
- fprintf(output, "\t/* %d */\n", i);
+ fprintf(output, "\t/* %d */\n", i + f->firstchar);
idx = i * f->stride * f->fontheight;
for (y = 0; y < f->fontheight; y++) {
for (x = 0; x < f->stride; x++) {
@@ -234,6 +238,79 @@ write_header(const char *filename, struc
}
void
+double_pixels(uint8_t *inbuf, uint16_t *outbuf, int bytes)
+{
+ int i, j;
+ uint16_t outmask, out;
+ uint8_t in, inmask;
+
+ for (i = 0; i < bytes; i++) {
+ inmask = 0x80;
+ outmask = 0xc000;
+ out = 0;
+ in = inbuf[i];
+ for (j = 0; j < 8; j++) {
+ if (in & inmask) {
+ out |= outmask;
+ }
+ inmask = inmask >> 1;
+ outmask = outmask >> 2;
+ }
+ outbuf[i * 2] = htobe16(out);
+ }
+}
+
+void fill_dup(uint16_t *buf, int lines)
+{
+ int i;
+ for (i = 0; i < lines; i++) {
+ buf[2 * i + 1] = buf[2 * i];
+ }
+}
+
+void smoothe_pixels(uint16_t *buf, int lines)
+{
+ int i, j, topright, topleft, botright, botleft;
+ uint16_t pmask, in, prev, next, out;
+ for (i = 0; i < lines; i++) {
+ pmask = 0xc000;
+ in = be16toh(buf[i]);
+ out = in;
+ prev = next = 0;
+ if (i > 1) prev = be16toh(buf[i - 2]);
+ if (i < (lines - 2)) next = be16toh(buf[i + 2]);
+ for (j = 0; j < 8; j++) {
+ if ((in & pmask) == 0) {
+ /* empty pixel, check surroundings */
+ topright = topleft = botright = botleft = 0;
+ if (((i & 1) == 0) && (j < 6))
+ topright = (((prev & pmask) == pmask) &&
+ ((prev & (pmask >> 2)) != 0) &&
+ ((in & (pmask >> 2)) != 0));
+ if (((i & 1) == 0) && (j > 0))
+ topleft = (((prev & pmask) == pmask) &&
+ ((prev & (pmask << 2)) != 0) &&
+ ((in & (pmask << 2)) != 0));
+ if ((i & 1) && (j < 6))
+ botright = (((next & pmask) == pmask) &&
+ ((next & (pmask >> 2)) != 0) &&
+ ((in & (pmask >> 2)) != 0));
+ if ((i & 1) && (j > 0))
+ botleft = (((next & pmask) == pmask) &&
+ ((next & (pmask << 2)) != 0) &&
+ ((in & (pmask << 2)) != 0));
+ if ((topright + topleft + botright + botleft) == 1) {
+ if (topleft || botleft) out |= pmask << 1;
+ if (topright || botright) out |= pmask >> 1;
+ }
+ }
+ pmask = pmask >> 2;
+ }
+ buf[i] = htobe16(out);
+ }
+}
+
+void
interpret(FILE *foo)
{
char line[128], *arg, name[64] = "foo", *buffer, *cbitmap;
@@ -404,18 +481,59 @@ interpret(FILE *foo)
}
/* now stuff it into a something wsfont understands */
- f.fontwidth = width /*(width + 3) & ~3*/;
- f.fontheight = height;
f.firstchar = first;
f.numchars = last - first + 1;
- f.stride = stride;
f.encoding = encoding;
if (fontname[0] == 0) {
f.name = name;
} else f.name = fontname;
f.bitorder = WSDISPLAY_FONTORDER_L2R;
f.byteorder = WSDISPLAY_FONTORDER_L2R;
- f.data = &buffer[first * charsize];
+
+ if (scale) {
+ uint16_t *outbuf;
+ uint8_t *inbuf;
+ int i;
+
+ if (stride != 1) err(EXIT_FAILURE,
+ "scaling works only on fonts up to 8 pixels wide\n");
+ f.fontwidth = width * 2 /*(width + 3) & ~3*/;
+ f.fontheight = height * 2;
+ f.stride = stride * 2;
+ outbuf = calloc(1, f.numchars * charsize * 4);
+ if (outbuf == NULL) err(EXIT_FAILURE,
+ "failed to allocete memory for scale buffer\n");
+ f.data = outbuf;
+ inbuf = &buffer[first * charsize];
+ for (i = 0; i < f.numchars; i++) {
+ double_pixels(inbuf, outbuf, charsize);
+ fill_dup(outbuf, charsize);
+ if (smoothe) smoothe_pixels(outbuf, charsize * 2);
+ inbuf += charsize;
+ outbuf += charsize * 2;
+ }
+
+ } else {
+ f.fontwidth = width /*(width + 3) & ~3*/;
+ f.fontheight = height;
+ f.stride = stride;
+ f.data = &buffer[first * charsize];
+ }
+if (0) {
+ int i;
+ uint16_t pixbuf[16];
+ double_pixels(&buffer[charsize * 'Q'], pixbuf, charsize);
+ fill_dup(pixbuf, charsize);
+ for (i = 0; i < charsize * 2; i++) {
+ printf("%2d: ", i);
+ dump_line((char *)&pixbuf[i], 2);
+ }
+ smoothe_pixels(pixbuf, charsize * 2);
+ for (i = 0; i < charsize * 2; i++) {
+ printf("%2d: ", i);
+ dump_line((char *)&pixbuf[i], 2);
+ }
+}
if (ofile == NULL) {
int fdev = open("/dev/wsfont", O_RDWR, 0);
@@ -428,16 +546,16 @@ interpret(FILE *foo)
}
else {
if (header == 0)
- write_wsf(ofile, &f, buffer, buflen);
+ write_wsf(ofile, &f);
else
- write_header(ofile, &f, buffer, buflen);
+ write_header(ofile, &f);
}
}
__dead void
usage()
{
- fprintf(stderr, "Usage: %s [-vdhf] [-e encoding] [-N name] "
+ fprintf(stderr, "Usage: %s [-vdhf2s] [-e encoding] [-N name] "
"[-o ofile.wsf] font.bdf\n", getprogname());
exit(EXIT_FAILURE);
}
@@ -449,7 +567,7 @@ main(int argc, char *argv[])
const char *encname = NULL;
int c;
- while ((c = getopt(argc, argv, "e:o:N:vdhf")) != -1) {
+ while ((c = getopt(argc, argv, "e:o:N:vdhf2s")) != -1) {
switch (c) {
/* font encoding */
@@ -480,6 +598,12 @@ main(int argc, char *argv[])
case 'f':
force = 1;
break;
+ case '2':
+ scale = 1;
+ break;
+ case 's':
+ smoothe = 1;
+ break;
case 'N':
strncpy(fontname, optarg, 64);
break;