The earlier version of this patch leaked memory if a font was locked multiple times.
This version fixes the leak: Index: dev/rasops/rasops.c =================================================================== RCS file: /cvs/src/sys/dev/rasops/rasops.c,v retrieving revision 1.69 diff -u -p -r1.69 rasops.c --- dev/rasops/rasops.c 18 Jan 2023 11:08:49 -0000 1.69 +++ dev/rasops/rasops.c 18 Jan 2023 23:55:25 -0000 @@ -561,7 +561,7 @@ rasops_pack_cattr(void *cookie, int fg, if ((flg & WSATTR_HILIT) != 0 && fg < 8) fg += 8; - *attr = (bg << 16) | (fg << 24) | (flg & WSATTR_UNDERLINE); + *attr = (bg << 16) | (fg << 24) | flg; return (0); } @@ -585,7 +585,7 @@ rasops_pack_mattr(void *cookie, int fg, bg = swap; } - *attr = (bg << 16) | (fg << 24) | (flg & WSATTR_UNDERLINE); + *attr = (bg << 16) | (fg << 24) | flg; return (0); } Index: dev/rasops/rasops32.c =================================================================== RCS file: /cvs/src/sys/dev/rasops/rasops32.c,v retrieving revision 1.13 diff -u -p -r1.13 rasops32.c --- dev/rasops/rasops32.c 18 Jan 2023 11:08:49 -0000 1.13 +++ dev/rasops/rasops32.c 18 Jan 2023 23:55:25 -0000 @@ -107,7 +107,26 @@ rasops32_putchar(void *cookie, int row, } } else { uc -= ri->ri_font->firstchar; - fr = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale; + + /* Choose font data based on bold and italic attributes */ + + u_char * font_dataset; + + switch (attr & (WSATTR_HILIT | WSATTR_ITALIC)) { + case WSATTR_HILIT: + font_dataset=(u_char *)ri->ri_font->data_bold; + break; + case WSATTR_ITALIC: + font_dataset=(u_char *)ri->ri_font->data_italic; + break; + case (WSATTR_HILIT | WSATTR_ITALIC): + font_dataset=(u_char *)ri->ri_font->data_bolditalic; + break; + default: + font_dataset=(u_char *)ri->ri_font->data; + } + + fr = (font_dataset + uc * ri->ri_fontscale); fs = ri->ri_font->stride; /* double-pixel special cases for the common widths */ Index: dev/wscons/wsconsio.h =================================================================== RCS file: /cvs/src/sys/dev/wscons/wsconsio.h,v retrieving revision 1.98 diff -u -p -r1.98 wsconsio.h --- dev/wscons/wsconsio.h 15 Jul 2022 17:57:27 -0000 1.98 +++ dev/wscons/wsconsio.h 18 Jan 2023 23:55:27 -0000 @@ -536,6 +536,9 @@ struct wsdisplay_font { #define WSDISPLAY_FONTORDER_R2L 2 void *cookie; void *data; + void *data_bold; + void *data_italic; + void *data_bolditalic; }; #define WSDISPLAYIO_LDFONT _IOW ('W', 77, struct wsdisplay_font) #define WSDISPLAYIO_LSFONT _IOWR('W', 78, struct wsdisplay_font) Index: dev/wscons/wsdisplayvar.h =================================================================== RCS file: /cvs/src/sys/dev/wscons/wsdisplayvar.h,v retrieving revision 1.38 diff -u -p -r1.38 wsdisplayvar.h --- dev/wscons/wsdisplayvar.h 13 Sep 2020 10:05:46 -0000 1.38 +++ dev/wscons/wsdisplayvar.h 18 Jan 2023 23:55:27 -0000 @@ -99,6 +99,7 @@ struct wsdisplay_emulops { #define WSATTR_BLINK 4 #define WSATTR_UNDERLINE 8 #define WSATTR_WSCOLORS 16 +#define WSATTR_ITALIC 32 }; #define WSSCREEN_NAME_SIZE 16 Index: dev/wscons/wsemul_vt100_subr.c =================================================================== RCS file: /cvs/src/sys/dev/wscons/wsemul_vt100_subr.c,v retrieving revision 1.29 diff -u -p -r1.29 wsemul_vt100_subr.c --- dev/wscons/wsemul_vt100_subr.c 12 Jan 2023 20:39:37 -0000 1.29 +++ dev/wscons/wsemul_vt100_subr.c 18 Jan 2023 23:55:27 -0000 @@ -588,6 +588,9 @@ wsemul_vt100_handle_csi(struct wsemul_vt case 1: /* bold */ flags |= WSATTR_HILIT; break; + case 3: /* italic */ + flags |= WSATTR_ITALIC; + break; case 4: /* underline */ flags |= WSATTR_UNDERLINE; break; @@ -599,6 +602,9 @@ wsemul_vt100_handle_csi(struct wsemul_vt break; case 22: /* ~bold VT300 only */ flags &= ~WSATTR_HILIT; + break; + case 23: /* ~italic */ + flags &= ~WSATTR_ITALIC; break; case 24: /* ~underline VT300 only */ flags &= ~WSATTR_UNDERLINE; Index: dev/wsfont/wsfont.c =================================================================== RCS file: /cvs/src/sys/dev/wsfont/wsfont.c,v retrieving revision 1.62 diff -u -p -r1.62 wsfont.c --- dev/wsfont/wsfont.c 4 Apr 2022 19:53:15 -0000 1.62 +++ dev/wsfont/wsfont.c 18 Jan 2023 23:55:29 -0000 @@ -586,6 +586,72 @@ wsfont_lock(int cookie, struct wsdisplay lc = ++ent->lockcount; *ptr = ent->font; + +#define FONT_DATA ((*ptr)->data) +#define FONT_DATA_BOLD ((*ptr)->data_bold) +#define FONT_DATA_ITALIC ((*ptr)->data_italic) +#define FONT_DATA_BOLDITALIC ((*ptr)->data_bolditalic) +#define FONT_SLANT ((((*ptr)->fontheight))/2) +#define FONT_BYTES_PER_GLYPH (((*ptr)->stride) * (((*ptr)->fontheight))) +#define FONT_DATA_LEN FONT_BYTES_PER_GLYPH * ((*ptr)->numchars) +#define FONT_STRIDE ((*ptr)->stride) + + int i, j, row_data; + if (lc == 1) { + /* + * Create a bold version of the font: + * + * To produce the bold effect, we simply duplicate the + * set bits of the pixel data offset one pixel to the + * right, effectively 'overprinting' the glyph. + * Better algorithms probably exist. + */ + (*ptr)->data_bold=malloc(FONT_DATA_LEN, M_TEMP, + M_WAITOK); + for (i=0; i < FONT_DATA_LEN ; i++) { + *(unsigned char *)(FONT_DATA_BOLD + i) = + *(unsigned char *)(FONT_DATA + i) | + (*(unsigned char *)(FONT_DATA + i) >> 1) ; + } + + /* + * Create an italic version of the font: + * + * Pixel data is increasingly offset to the left as we + * progress down the rows from the top of each glyph. + * + * To minimise the overall visual shift to the left, we + * shift a fixed one bit to the right on each row. + */ + (*ptr)->data_italic=malloc(FONT_DATA_LEN, M_TEMP, + M_WAITOK); + for (i=0; i < FONT_DATA_LEN ; i += FONT_STRIDE) { + row_data=0; + for (j=0; j < FONT_STRIDE; j++) { + row_data |=((*(unsigned char *) + (FONT_DATA + i + j) << (8 * + (FONT_STRIDE-j-1)))); + } + row_data=row_data << (i % FONT_BYTES_PER_GLYPH / + FONT_SLANT) >> 1; + for (j=0; j < FONT_STRIDE; j++) { + *(unsigned char *)(FONT_DATA_ITALIC + i + + j) = (row_data >> (8 * + (FONT_STRIDE - j - 1)) & 0xFF); + } + } + /* + * Create a bold and italic version of the font: + */ + (*ptr)->data_bolditalic=malloc(FONT_DATA_LEN, M_TEMP, + M_WAITOK); + for (i=0; i < FONT_DATA_LEN ; i++) { + *(unsigned char *)(FONT_DATA_BOLDITALIC + i) = + *(unsigned char *)(FONT_DATA_ITALIC + i) | + (*(unsigned char *)(FONT_DATA_ITALIC + i) + >> 1) ; + } + } } else lc = -1; @@ -600,6 +666,7 @@ int wsfont_unlock(int cookie) { struct font *ent; + struct wsdisplay_font *ptr; int s, lc; s = splhigh(); @@ -607,7 +674,13 @@ wsfont_unlock(int cookie) if ((ent = wsfont_find0(cookie)) != NULL) { if (ent->lockcount == 0) panic("wsfont_unlock: font not locked"); + ptr = ent->font; lc = --ent->lockcount; + if (lc == 0) { + free (ptr->data_bold, M_TEMP, 0); + free (ptr->data_italic, M_TEMP, 0); + free (ptr->data_bolditalic, M_TEMP, 0); + } } else lc = -1;