From 9d1aac189e6e581e5c15ccff239ba4e8a59f7648 Mon Sep 17 00:00:00 2001 From: Ray Chason Date: Fri, 14 Aug 2026 21:15:36 -0400 Subject: [PATCH] Convert TTY status to Xft --- include/winX.h | 2 +- win/X11/winX.c | 15 +++++- win/X11/winstat.c | 119 ++++++++++++++++++++++++++++++++++++++++++---- win/X11/wintext.c | 2 +- 4 files changed, 126 insertions(+), 12 deletions(-) diff --git a/include/winX.h b/include/winX.h index d56c23e4a..952ddcec4 100644 --- a/include/winX.h +++ b/include/winX.h @@ -382,7 +382,7 @@ extern Boolean nhCvtStringToPixel(Display *, XrmValuePtr, Cardinal *, extern void get_window_frame_extents(Widget, long *, long *, long *, long *); extern void get_widget_window_geometry(Widget, int *, int *, int *, int *); extern char *fontname_boldify(const char *); -extern Dimension nhFontHeight(Widget); +extern Dimension nhFontHeight(Widget, int); extern char key_event_to_char(XKeyEvent *); extern void msgkey(Widget, XtPointer, XEvent *, Boolean *); extern void highlight_yn(boolean); diff --git a/win/X11/winX.c b/win/X11/winX.c index 4596190b4..4889ac74a 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -752,11 +752,22 @@ nhFreePixel( * assumption of ascent + descent is not always valid. */ Dimension -nhFontHeight(Widget w) +nhFontHeight(Widget w, int win_type) { +#ifdef USE_XFT + + XftFont *font = X11_new_font(w, 0, win_type); + Dimension height = font->height; + X11_release_font(w, font); + return height; + +#else /* !USE_XFT */ + Arg args[1]; XFontStruct *fs; + nhUse(win_type); + #ifdef _XawTextSink_h Widget sink = NULL; XawTextPosition pos = 0; @@ -776,6 +787,8 @@ nhFontHeight(Widget w) /* Assume font height is ascent + descent. */ return fs->ascent + fs->descent; + +#endif /* ?USE_XFT */ } static String *default_resource_data = 0, /* NULL-terminated arrays */ diff --git a/win/X11/winstat.c b/win/X11/winstat.c index ed8f5da42..024045e6f 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -558,7 +558,7 @@ create_tty_status(Widget parent, Widget top) X11_status_widget = XtCreateManagedWidget("status_form", windowWidgetClass, form, args, num_args); - int height = nhFontHeight(X11_status_widget) * 3; + int height = nhFontHeight(X11_status_widget, NHW_STATUS) * 3; num_args = 0; XtSetArg(args[num_args], XtNheight, height); num_args++; XtSetValues(form, args, num_args); @@ -618,7 +618,7 @@ tty_status_redraw(Widget w) num_args = 0; XtSetArg(args[num_args], XtNwidth, &width); num_args++; XtGetValues(w, args, num_args); - int height = nhFontHeight(w); + int height = nhFontHeight(w, NHW_STATUS); int x = 0; int y = 0; @@ -770,17 +770,116 @@ tty_render_text(Widget w, const XRectangle *clip, int x, int y, nhUse(attr); #endif - Arg args[5]; - Cardinal num_args; - XGCValues values; - Pixel fgpixel, bgpixel; - XFontStruct *font; - XFontStruct *font_italic = NULL; /* custodial */ int goldwidth = 0; /* Get the colors */ + Pixel fgpixel, bgpixel; tty_status_colors(w, color, attr, &fgpixel, &bgpixel); +#ifdef USE_XPM + + /* Get the font */ + XftFont *font = X11_new_font(w, (attr & HL_BOLD) != 0, NHW_STATUS); + + /* Get the drawing resources */ + Display *display = XtDisplay(w); + Screen *screen = DefaultScreenOfDisplay(display); + Visual *visual = DefaultVisualOfScreen(screen); + Colormap cmap = DefaultColormapOfScreen(screen); + XftDraw *draw = XftDrawCreate(display, XtWindow(w), visual, cmap); + + /* Convert the colors to Xft form */ + XftColor fgcolor, bgcolor; + X11_new_color(w, fgpixel, &fgcolor); + X11_new_color(w, bgpixel, &bgcolor); + + /* If drawing a hitpoint bar, we'll need a clipping rectangle */ + if (clip != NULL) { + XftDrawSetClipRectangles(draw, 0, 0, clip, 1); + } + + /* Gold will begin with a glyph string. Convert this to the proper + character, which might possibly be Unicode */ + if (fld == BL_GOLD && memcmp(text, "\\G", 2) == 0) { + char *end; + unsigned long glyphcode = strtoul(text+2, &end, 16); + if ((glyphcode >> 16) == (unsigned) svc.context.rndencode && *end == ':') { + /* We have a proper glyph code */ + glyph_info glyphinfo; + glyphcode &= 0xFFFF; + map_glyphinfo(0, 0, glyphcode, 0, &glyphinfo); + X11_map_symbol goldsym = X11_glyph_char(&glyphinfo); + + /* Get the width of the gold symbol */ + XGlyphInfo extents; +#ifdef ENHANCED_SYMBOLS + FcChar32 goldch = goldsym; + XftTextExtents32(display, font, &goldch, 1, &extents); +#else /* !ENHANCED_SYMBOLS */ + FcChar8 goldch = goldsym; + XftTextExtents8(display, font, &goldch, 1, &extents); +#endif /* ?ENHANCED_SYMBOLS */ + goldwidth = extents.width - extents.x; + + /* Render the gold symbol */ + XftDrawRect(draw, &bgcolor, x, y, goldwidth, font->height); +#ifdef ENHANCED_SYMBOLS + XftDrawString32(draw, &fgcolor, font, x, y + font->ascent, &goldch, 1); +#else /* !ENHANCED_SYMBOLS */ + XftDrawString8(draw, &fgcolor, font, x, y + font->ascent, &goldch, 1); +#endif /* ?ENHANCED_SYMBOLS */ + + text = end; + } + } + + /* Get the width of the rendered string, not including goldwidth */ + XGlyphInfo extents; + XftTextExtents8(display, font, (const FcChar8 *) text, strlen(text), &extents); + int width = extents.width - extents.x; + + /* Place version on the right */ + if (fld == BL_VERS) { + Cardinal num_args = 0; + Arg args[1]; + Dimension wwidth; + XtSetArg(args[num_args], XtNwidth, &wwidth); num_args++; + XtGetValues(w, args, num_args); + int x2 = wwidth - width; + if (x2 > x) { + x = x2; + } + } + + /* Render the string */ + XftDrawRect(draw, &bgcolor, x + goldwidth, y, width, font->height); + XftDrawString8(draw, &fgcolor, font, + x + goldwidth, y + font->ascent, + (const FcChar8 *) text, strlen(text)); + width += goldwidth; + +#ifdef STATUS_HILITES + /* Implement underline */ + if (attr & HL_ULINE) { + XftDrawRect(draw, &fgcolor, x, y + font->ascent, width, 1); + } +#endif /* STATUS_HILITES */ + + /* Release resources */ + + XftColorFree(display, visual, cmap, &fgcolor); + XftColorFree(display, visual, cmap, &bgcolor); + XftDrawDestroy(draw); + X11_release_font(w, font); + +#else /* !USE_XPM */ + + Arg args[5]; + Cardinal num_args; + XGCValues values; + XFontStruct *font; + XFontStruct *font_italic = NULL; /* custodial */ + values.foreground = fgpixel; values.background = bgpixel; @@ -805,6 +904,7 @@ tty_render_text(Widget w, const XRectangle *clip, int x, int y, } } + /* Get a graphics context */ values.font = font->fid; values.function = GXcopy; GC ggc = XtGetGC(w, @@ -907,6 +1007,7 @@ tty_render_text(Widget w, const XRectangle *clip, int x, int y, if (font_italic != NULL) { XFreeFont(XtDisplay(w), font_italic); } +#endif /* ?USE_XPM */ /* Caller will advance x by the width */ return width; @@ -1139,7 +1240,7 @@ create_status_window_fancy(struct xwindow *wp, /* window pointer */ &right_margin); num_args++; XtGetValues(wp->w, args, num_args); - wp->pixel_height = 2 * nhFontHeight(wp->w) + top_margin + bottom_margin; + wp->pixel_height = 2 * nhFontHeight(wp->w, NHW_STATUS) + top_margin + bottom_margin; wp->pixel_width = COLNO * fs->max_bounds.width + left_margin + right_margin; diff --git a/win/X11/wintext.c b/win/X11/wintext.c index 9c7b98a2b..57c45540b 100644 --- a/win/X11/wintext.c +++ b/win/X11/wintext.c @@ -154,7 +154,7 @@ display_text_window(struct xwindow *wp, boolean blocking) width = text_info->max_width + text_info->extra_width; text_info->blocked = blocking; text_info->destroy_on_ack = FALSE; - font_height = nhFontHeight(wp->w); + font_height = nhFontHeight(wp->w, NHW_TEXT); /* * Calculate the number of lines to use. First, find the number of