From 0f39437315f04841f4e804818dce8baa5c5f629f Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Sat, 8 Aug 2026 18:01:06 -0400 Subject: [PATCH] Implement underline and italic --- include/winX.h | 1 + win/X11/winX.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ win/X11/winstat.c | 24 ++++++++++++++++++++++-- 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/include/winX.h b/include/winX.h index 9cc55e09a..935fd5f5c 100644 --- a/include/winX.h +++ b/include/winX.h @@ -514,6 +514,7 @@ extern void X11_preference_update(const char *); extern void X11_update_inventory(int); extern win_request_info *X11_ctrl_nhwindow(winid, int, win_request_info *); extern X11_map_symbol X11_glyph_char(const glyph_info *); +extern XFontStruct *X11_italic_font(Display *, XFontStruct *); #ifdef ENHANCED_SYMBOLS extern XFontStruct *X11_unicode_font(Display *, XFontStruct *); #endif diff --git a/win/X11/winX.c b/win/X11/winX.c index 1b3089e9e..2abf03c20 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -3004,6 +3004,51 @@ X11_glyph_char(const glyph_info *glyphinfo) #endif } +/* Given an XFontStruct, return a corresponding italic font */ +XFontStruct * +X11_italic_font(Display *display, XFontStruct *font) +{ + Atom font_atom; + if (!XGetFontProperty(font, XA_FONT, &font_atom)) { + return NULL; + } + + const char *font_name = XGetAtomName(display, font_atom); + if (font_name == NULL) { + return NULL; + } + + /* Proceed to the slant */ + unsigned dashes = 4; + const char *p = font_name; + while (dashes != 0) { + const char *q = strchr(p, '-'); + if (q == NULL) { + break; + } + p = q + 1; + --dashes; + } + + /* Try substituting "i" for the slant */ + char italic_font[BUFSZ]; + int pre = (int)(p - font_name); + p += strcspn(p, "-"); + Snprintf(italic_font, sizeof(italic_font), "%.*sI%s", pre, font_name, p); + XFontStruct *font2 = XLoadQueryFont(display, italic_font); + printf("italic font=%p\n", (void *)font2); + if (font2 != NULL) { + return font2; + } + + /* Try substituting "o" */ + Snprintf(italic_font, sizeof(italic_font), "%.*sO%s", pre, font_name, p); + font2 = XLoadQueryFont(display, italic_font); + printf("oblique font=%p\n", (void *)font2); + + return font2; +} + #ifdef ENHANCED_SYMBOLS /* Given an XFontStruct, return a corresponding font that supports Unicode */ XFontStruct * diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 8d7f3230c..8d09f3ae2 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -1264,6 +1264,7 @@ tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, XGCValues values; Pixel fgpixel, bgpixel; XFontStruct *font; + XFontStruct *font_italic = NULL; /* custodial */ int goldwidth = 0; /* Get default foreground and background colors, and font */ @@ -1294,6 +1295,15 @@ tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, font = wp->boldfs; } + /* Implement italic font */ + if (attr & HL_ITALIC) { + /* font may also be bold */ + font_italic = X11_italic_font(XtDisplay(w), font); + if (font_italic != NULL) { + font = font_italic; + } + } + /* Implement dim text */ if (attr & HL_DIM) { fgpixel = (fgpixel & 0xFEFEFE) >> 1; @@ -1370,18 +1380,28 @@ tty_render_text(Widget w, int x, int y, const char *text, int color, int attr, } /* Get the width of the rendered string */ - int width = XTextWidth(font, text, strlen(text)); + int width = XTextWidth(font, text, strlen(text)) + goldwidth; /* Render the string */ XDrawImageString(XtDisplay(w), XtWindow(w), ggc, x + goldwidth, y + font->max_bounds.ascent, text, strlen(text)); + /* Implement underline */ + if (attr & HL_ULINE) { + XDrawLine(XtDisplay(w), XtWindow(w), ggc, + x, y + font->max_bounds.ascent, + x + width - 1, y + font->max_bounds.ascent); + } + /* Release resources */ XtReleaseGC(w, ggc); + if (font_italic != NULL) { + XFreeFont(XtDisplay(w), font_italic); + } /* Caller will advance x by the width */ - return goldwidth + width; + return width; } /*ARGSUSED*/