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;
 

Reply via email to