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;