untrusted comment: verify with signify key from exoticsilicon.com RWRn5d3Yx35u0zSZcF2Xsdhizzvw4T/z22wKwMOgqulDJiVRI3/t8z1uKcL5mlb3Hgb6h02kfwRDeAWbc6yFCZ41iOpQWHe9/Qo= # Patch to add true bold and italic font rendering on the OpenBSD console. # This version of the patch applies to OpenBSD 7.2-release. # For more information regarding this patch, please visit: # https://research.exoticsilicon.com/ # THIS PATCH IS PROVIDED 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL # EXOTIC SILICON BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA OR PROFITS; # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS PATCH, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --- dev/wscons/wsemul_vt100_subr.c.dist Mon May 25 06:55:49 2020 +++ dev/wscons/wsemul_vt100_subr.c Wed Jan 18 17:24:20 2023 @@ -549,6 +549,9 @@ case 1: /* bold */ flags |= WSATTR_HILIT; break; + case 3: /* italic */ + flags |= WSATTR_ITALIC; + break; case 4: /* underline */ flags |= WSATTR_UNDERLINE; break; @@ -560,6 +563,9 @@ 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; --- dev/wscons/wsdisplayvar.h.dist Sun Sep 13 07:05:46 2020 +++ dev/wscons/wsdisplayvar.h Wed Jan 18 17:23:08 2023 @@ -99,6 +99,7 @@ #define WSATTR_BLINK 4 #define WSATTR_UNDERLINE 8 #define WSATTR_WSCOLORS 16 +#define WSATTR_ITALIC 32 }; #define WSSCREEN_NAME_SIZE 16 --- dev/wscons/wsconsio.h.dist Fri Jul 15 14:57:27 2022 +++ dev/wscons/wsconsio.h Wed Jan 18 17:22:30 2023 @@ -536,6 +536,9 @@ #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) --- dev/wsfont/wsfont.c.dist Mon Apr 4 16:53:15 2022 +++ dev/wsfont/wsfont.c Wed Jan 18 19:55:16 2023 @@ -586,6 +586,71 @@ 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 +665,7 @@ wsfont_unlock(int cookie) { struct font *ent; + struct wsdisplay_font *ptr; int s, lc; s = splhigh(); @@ -607,7 +673,13 @@ 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; --- dev/rasops/rasops.c.dist Thu Jul 23 06:17:03 2020 +++ dev/rasops/rasops.c Wed Jan 18 17:17:31 2023 @@ -568,14 +568,8 @@ if ((flg & WSATTR_HILIT) != 0) fg += 8; - flg = ((flg & WSATTR_UNDERLINE) ? 1 : 0); + flg = ((flg & WSATTR_UNDERLINE) ? (flg | 1) : flg); - if (rasops_isgray[fg]) - flg |= 2; - - if (rasops_isgray[bg]) - flg |= 4; - *attr = (bg << 16) | (fg << 24) | flg; return (0); } @@ -600,7 +594,7 @@ bg = swap; } - *attr = (bg << 16) | (fg << 24) | ((flg & WSATTR_UNDERLINE) ? 7 : 6); + *attr = (bg << 16) | (fg << 24) | ((flg & WSATTR_UNDERLINE) ? (flg | 1) : flg); return (0); } --- dev/rasops/rasops32.c.dist Mon Jul 20 09:40:45 2020 +++ dev/rasops/rasops32.c Wed Jan 18 17:18:46 2023 @@ -107,7 +107,26 @@ } } 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 */