aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Gladkov <gladkov.alexey@gmail.com>2023-06-21 14:18:30 +0200
committerAlexey Gladkov <gladkov.alexey@gmail.com>2023-06-22 13:28:27 +0200
commit830459d78081dc9dda12dc4101fae06ea7070c30 (patch)
tree40e0ac70c4b2387683a0ed77806d69bae4702b8a
parenta1fde28af59dbca1483f54d957a523765e6ea335 (diff)
downloadkbd-830459d78081dc9dda12dc4101fae06ea7070c30.tar.gz
Respect height when writing font header
The psf2 header contains a height field, but is almost always ignored and calculated based on other parameters. This breaks saving tall fonts from the kernel. Signed-off-by: Alexey Gladkov <gladkov.alexey@gmail.com>
-rw-r--r--src/libkfont/kfont.h3
-rw-r--r--src/libkfont/psffontop.c18
-rw-r--r--src/libkfont/setfont.c29
-rw-r--r--src/psfxtable.c5
4 files changed, 39 insertions, 16 deletions
diff --git a/src/libkfont/kfont.h b/src/libkfont/kfont.h
index 4c2b0221..1f51b6d9 100644
--- a/src/libkfont/kfont.h
+++ b/src/libkfont/kfont.h
@@ -270,7 +270,8 @@ void kfont_disactivatemap(int fd);
int kfont_read_psffont(struct kfont_context *ctx,
FILE *fontf, unsigned char **allbufp, unsigned int *allszp,
unsigned char **fontbufp, unsigned int *fontszp,
- unsigned int *fontwidthp, unsigned int *fontlenp, unsigned int fontpos0,
+ unsigned int *fontwidthp, unsigned int *fontheightp,
+ unsigned int *fontlenp, unsigned int fontpos0,
struct unicode_list **uclistheadsp)
__attribute__((nonnull(1)));
diff --git a/src/libkfont/psffontop.c b/src/libkfont/psffontop.c
index 329b9196..84cba8ff 100644
--- a/src/libkfont/psffontop.c
+++ b/src/libkfont/psffontop.c
@@ -196,8 +196,8 @@ int
kfont_read_psffont(struct kfont_context *ctx,
FILE *fontf, unsigned char **allbufp, unsigned int *allszp,
unsigned char **fontbufp, unsigned int *fontszp,
- unsigned int *fontwidthp, unsigned int *fontlenp,
- unsigned int fontpos0,
+ unsigned int *fontwidthp, unsigned int *fontheightp,
+ unsigned int *fontlenp, unsigned int fontpos0,
struct unicode_list **uclistheadsp)
{
unsigned char *inputbuf;
@@ -226,7 +226,7 @@ kfont_read_psffont(struct kfont_context *ctx,
inputlth = *allszp;
}
- unsigned int fontlen, fontwidth, charsize, hastable, ftoffset;
+ unsigned int fontlen, fontwidth, fontheight, charsize, hastable, ftoffset;
int utf8;
if (inputlth >= sizeof(struct psf1_header) && PSF1_MAGIC_OK(inputbuf)) {
@@ -243,6 +243,7 @@ kfont_read_psffont(struct kfont_context *ctx,
hastable = (psfhdr->mode & (PSF1_MODEHASTAB | PSF1_MODEHASSEQ));
ftoffset = sizeof(struct psf1_header);
fontwidth = 8;
+ fontheight= 0;
utf8 = 0;
} else if (inputlth >= sizeof(struct psf2_header) && PSF2_MAGIC_OK(inputbuf)) {
struct psf2_header psfhdr;
@@ -260,6 +261,7 @@ kfont_read_psffont(struct kfont_context *ctx,
hastable = (flags & PSF2_HAS_UNICODE_TABLE);
ftoffset = assemble_uint32((unsigned char *)&psfhdr.headersize);
fontwidth = assemble_uint32((unsigned char *)&psfhdr.width);
+ fontheight= assemble_uint32((unsigned char *)&psfhdr.height);
utf8 = 1;
} else
return -EX_DATAERR; /* not psf */
@@ -274,6 +276,12 @@ kfont_read_psffont(struct kfont_context *ctx,
return -EX_DATAERR;
}
+ if (!fontheight) {
+ unsigned int bytewidth;
+ bytewidth = (fontwidth + 7) / 8;
+ fontheight = (fontlen * charsize) / (bytewidth * fontlen);
+ }
+
unsigned int i = ftoffset + fontlen * charsize;
if (i > inputlth || (!hastable && i != inputlth)) {
@@ -289,6 +297,8 @@ kfont_read_psffont(struct kfont_context *ctx,
*fontlenp = fontlen;
if (fontwidthp)
*fontwidthp = fontwidth;
+ if (fontheightp)
+ *fontheightp = fontheight;
if (!uclistheadsp)
return 0; /* got font, don't need unicode_list */
@@ -418,7 +428,7 @@ writepsffontheader(struct kfont_context *ctx,
bytewidth = (width + 7) / 8;
charsize = bytewidth * height;
- if ((fontlen != 256 && fontlen != 512) || width != 8)
+ if ((fontlen != 256 && fontlen != 512) || width != 8 || height > 32)
*psftype = 2;
if (*psftype == 2) {
diff --git a/src/libkfont/setfont.c b/src/libkfont/setfont.c
index 9d31adc7..7b28541c 100644
--- a/src/libkfont/setfont.c
+++ b/src/libkfont/setfont.c
@@ -278,7 +278,7 @@ kfont_load_fonts(struct kfont_context *ctx,
{
const char *ifil;
unsigned char *inbuf, *fontbuf, *bigfontbuf;
- unsigned int inputlth, fontbuflth, fontsize, height, width, bytewidth;
+ unsigned int inputlth, fontbuflth, fontsize, height, width;
unsigned int bigfontbuflth, bigfontsize, bigheight, bigwidth;
unsigned char *ptr;
struct unicode_list *uclistheads;
@@ -316,9 +316,10 @@ kfont_load_fonts(struct kfont_context *ctx,
inbuf = fontbuf = NULL;
inputlth = fontbuflth = 0;
fontsize = 0;
+ height = 0;
if (kfont_read_psffont(ctx, kbdfile_get_file(fp), &inbuf,
- &inputlth, &fontbuf, &fontbuflth, &width, &fontsize,
+ &inputlth, &fontbuf, &fontbuflth, &width, &height, &fontsize,
bigfontsize, no_u ? NULL : &uclistheads)) {
KFONT_ERR(ctx, _("When loading several fonts, all must be psf fonts - %s isn't"),
kbdfile_get_pathname(fp));
@@ -326,8 +327,11 @@ kfont_load_fonts(struct kfont_context *ctx,
goto end;
}
- bytewidth = (width + 7) / 8;
- height = fontbuflth / (bytewidth * fontsize);
+ if (!height) {
+ unsigned int bytewidth;
+ bytewidth = (width + 7) / 8;
+ height = fontbuflth / (bytewidth * fontsize);
+ }
KFONT_INFO(ctx, _("Read %d-char %dx%d font from file %s"),
fontsize, width, height, kbdfile_get_pathname(fp));
@@ -388,7 +392,7 @@ kfont_load_font(struct kfont_context *ctx, int fd, const char *ifil,
struct kbdfile *fp;
char defname[20];
- unsigned int height, width, bytewidth;
+ unsigned int height, width;
int def = 0;
unsigned char *inbuf, *fontbuf;
unsigned int inputlth, fontbuflth, fontsize, offset;
@@ -439,14 +443,19 @@ kfont_load_font(struct kfont_context *ctx, int fd, const char *ifil,
inbuf = fontbuf = NULL;
inputlth = fontbuflth = fontsize = 0;
width = 8;
+ height = 0;
uclistheads = NULL;
if (!kfont_read_psffont(ctx, kbdfile_get_file(fp), &inbuf, &inputlth,
- &fontbuf, &fontbuflth, &width, &fontsize, 0, no_u ? NULL : &uclistheads)) {
+ &fontbuf, &fontbuflth, &width, &height, &fontsize, 0,
+ no_u ? NULL : &uclistheads)) {
/* we've got a psf font */
- bytewidth = (width + 7) / 8;
- height = fontbuflth / (bytewidth * fontsize);
+ if (!height) {
+ unsigned int bytewidth;
+ bytewidth = (width + 7) / 8;
+ height = fontbuflth / (bytewidth * fontsize);
+ }
ret = do_loadfont(ctx, fd, fontbuf, width, height, hwunit,
fontsize, kbdfile_get_pathname(fp));
@@ -607,8 +616,10 @@ save_font(struct kfont_context *ctx, int consolefd, const char *filename,
return -EX_OSERR;
/* save as efficiently as possible */
+ if (!height)
+ height = font_charheight(buf, ct, width);
+
bytewidth = (width + 7) / 8;
- height = font_charheight(buf, ct, width);
charsize = height * bytewidth;
kcharsize = vpitch * bytewidth;
diff --git a/src/psfxtable.c b/src/psfxtable.c
index a88f6d58..63221c44 100644
--- a/src/psfxtable.c
+++ b/src/psfxtable.c
@@ -143,7 +143,7 @@ int main(int argc, char **argv)
kbd_error(EX_CANTCREAT, 0, _("Unable to open file: %s: %m"), otname);
if (kfont_read_psffont(kfont, ifil, &inbuf, &inbuflth, &fontbuf,
- &fontbuflth, &width, &fontlen, 0,
+ &fontbuflth, &width, &height, &fontlen, 0,
itab ? NULL : &uclistheads) < 0)
kbd_error(EX_DATAERR, 0, _("Bad magic number on %s"), ifname);
@@ -155,7 +155,8 @@ int main(int argc, char **argv)
if (!bytewidth)
bytewidth = 1;
- height = charsize / bytewidth;
+ if (!height)
+ height = charsize / bytewidth;
hastable = (uclistheads != NULL);