Convert fancy status and menus to Xft

This commit is contained in:
Ray Chason
2026-08-19 09:37:41 +03:00
committed by Pasi Kallinen
parent 9e57c85b16
commit 7c9cf20d1d
5 changed files with 109 additions and 12 deletions
+1 -1
View File
@@ -551,7 +551,7 @@ extern void X11_new_color(Widget w, Pixel pixel, XftColor *color);
/* ### winlabel.c ### */
/* Functions for management of enhanced labels */
extern void X11_wrap_widget(Widget);
extern void X11_wrap_widget(Widget, int);
extern void X11_update_label(Widget);
extern void X11_set_attrs(Widget, unsigned);
extern void X11_set_highlight(Widget, boolean);
+103 -6
View File
@@ -28,8 +28,13 @@ typedef struct WidgetData {
boolean highlight;
/* Fonts for italic, bold and bold-italic */
#ifdef USE_XFT
int win_type;
XftFont *vfont[4];
#else /* !USE_XFT */
XFontStruct *font[4]; /* To use the fonts */
XFontStruct *font_ptr[4]; /* To free the fonts */
#endif /* ?USE_XFT */
/* Percentage bar */
unsigned percent;
@@ -57,7 +62,7 @@ static WidgetData *get_widget_data(Widget w);
* attribute flags and a percentage bar.
*/
void
X11_wrap_widget(Widget w)
X11_wrap_widget(Widget w, int win_type)
{
/* We shouldn't use this for anything other than labels and subclasses
of labels */
@@ -79,10 +84,16 @@ X11_wrap_widget(Widget w)
WidgetData *data = add_widget(w);
/* Copy resources from the created widget */
#ifdef USE_XFT
data->win_type = win_type;
allocate_font(w, data, 0);
#else /* !USE_XFT */
Cardinal num_args2 = 0;
Arg args2[1];
XtSetArg(args2[num_args2], XtNfont, &data->font[0]); num_args2++;
XtGetValues(w, args2, num_args2);
nhUse(win_type);
#endif /* ?USE_XFT */
/* Create the pixmap for the first time */
update_label(w, data);
@@ -184,7 +195,11 @@ update_label(Widget w, WidgetData *data)
font_idx |= font_italic;
allocate_font(w, data, font_idx);
}
#ifdef USE_XFT
XftFont *vfont = data->vfont[font_idx];
#else
XFontStruct *font = data->font[font_idx];
#endif
String label;
Boolean sens; /* Make dim if not sensitive */
@@ -222,11 +237,17 @@ update_label(Widget w, WidgetData *data)
}
/* Get the width of the line */
#ifdef USE_XFT
XGlyphInfo extents;
XftTextExtents8(display, vfont, (const FcChar8*) (label + i), line2, &extents);
int lwidth = extents.width - extents.x;
#else
int lwidth = XTextWidth(font, label + i, line2);
#endif
/* Update pixmap dimensions */
width = max(lwidth, width);
height += font->ascent + font->descent;
++height;
/* Advance to next line */
i += line1;
@@ -236,7 +257,14 @@ update_label(Widget w, WidgetData *data)
}
/* Always size for at least one line */
height = max(height, font->ascent + font->descent);
height = max(height, 1);
/* Convert height to pixels */
#ifdef USE_XFT
height *= vfont->height;
#else
height *= font->ascent + font->descent;
#endif
} else {
num_args = 0;
XtSetArg(args[num_args], XtNwidth, &width); num_args++;
@@ -285,11 +313,20 @@ update_label(Widget w, WidgetData *data)
if ((attrs & HL_BLINK) && X11_blink) {
values.foreground = values.background;
}
#ifdef USE_XFT
Visual *visual = DefaultVisualOfScreen(screen);
Colormap cmap = DefaultColormapOfScreen(screen);
XftDraw *draw = XftDrawCreate(display, new_pixmap, visual, cmap);
XftColor fgcolor, bgcolor;
X11_new_color(w, values.foreground, &fgcolor);
X11_new_color(w, values.background, &bgcolor);
#else /* !USE_XFT */
values.font = font->fid;
values.function = GXcopy;
GC ggc = XtGetGC(w,
GCFunction | GCForeground | GCBackground | GCFont,
&values);
#endif /* ?USE_XFT */
if (pass == 1) {
/* Percent bar will occupy this area */
XRectangle clip = {
@@ -298,18 +335,34 @@ update_label(Widget w, WidgetData *data)
.width = width * data->percent / 100,
.height = height
};
#ifdef USE_XFT
XftDrawSetClipRectangles(draw, 0, 0, &clip, 1);
#else /* !USE_XFT */
XSetClipRectangles(display, ggc, 0, 0, &clip, 1, Unsorted);
#endif /* ?USE_XFT */
}
/* Draw a border for inverse and highlight together */
/* Otherwise, fill with the background color */
#ifdef USE_XFT
if (!((attrs & HL_INVERSE) && data->highlight)) {
XftDrawRect(draw, &bgcolor, 0, 0, width, height);
} else {
XftDrawRect(draw, &fgcolor, 0, 0, width, height);
}
#else /* !USE_XFT */
if (!((attrs & HL_INVERSE) && data->highlight)) {
XSetForeground(display, ggc, values.background);
}
XFillRectangle(display, new_pixmap, ggc, 0, 0, width, height);
XSetForeground(display, ggc, values.foreground);
#endif /* ?USE_XFT */
#ifdef USE_XFT
int y = vfont->ascent;
#else /* !USE_XFT */
int y = font->max_bounds.ascent;
#endif /* ?USE_XFT */
size_t i = 0;
while (label[i] != '\0') {
size_t line1 = strcspn(label + i, "\n");
@@ -320,7 +373,13 @@ update_label(Widget w, WidgetData *data)
}
/* Get the width of the line */
#ifdef USE_XFT
XGlyphInfo extents;
XftTextExtents8(display, vfont, (const FcChar8*) (label + i), line2, &extents);
int lwidth = extents.width - extents.x;
#else
int lwidth = XTextWidth(font, label + i, line2);
#endif
/* Place the line horizontally */
int x = 0;
@@ -339,18 +398,32 @@ update_label(Widget w, WidgetData *data)
}
/* Render the line */
#ifdef USE_XFT
XftDrawRect(draw, &bgcolor, x, y - vfont->ascent, lwidth, vfont->height);
XftDrawString8(draw, &fgcolor, vfont, x, y,
(const FcChar8 *) (label + i), line2);
#else
XDrawImageString(display, new_pixmap, ggc,
x, y,
label + i, line2);
#endif
/* Draw the underline if requested */
if (attrs & HL_ULINE) {
#ifdef USE_XFT
XftDrawRect(draw, &fgcolor, x, y, lwidth, 1);
#else
XDrawLine(display, new_pixmap, ggc,
x, y,
x + lwidth - 1, y);
#endif
}
#ifdef USE_XFT
y += vfont->height;
#else
y += font->ascent + font->descent;
#endif
/* Advance to next line */
i += line1;
@@ -361,10 +434,23 @@ update_label(Widget w, WidgetData *data)
/* Ensure a one-pixel border if both inverse and highlight */
if ((attrs & HL_INVERSE) && data->highlight) {
#ifdef USE_XFT
XftDrawRect(draw, &fgcolor, 0, 0, width, 1);
XftDrawRect(draw, &fgcolor, 0, height-1, width, 1);
XftDrawRect(draw, &fgcolor, 0, 0, 1, height);
XftDrawRect(draw, &fgcolor, 0, height-1, 1, height);
#else
XDrawRectangle(display, new_pixmap, ggc, 0, 0, width-1, height-1);
#endif
}
#ifdef USE_XFT
XftColorFree(display, visual, cmap, &fgcolor);
XftColorFree(display, visual, cmap, &bgcolor);
XftDrawDestroy(draw);
#else
XtReleaseGC(w, ggc);
#endif
/* Set up to display the percent bar on the second pass */
if (data->percent == 0) {
@@ -377,8 +463,6 @@ update_label(Widget w, WidgetData *data)
/* Update the pixmap */
num_args = 0;
XtSetArg(args[num_args], XtNbitmap, new_pixmap); num_args++;
//XtSetArg(args[num_args], XtNwidth, width); num_args++;
//XtSetArg(args[num_args], XtNheight, height); num_args++;
XtSetValues(w, args, num_args);
if (data->pixmap != 0) {
XFreePixmap(display, data->pixmap);
@@ -390,8 +474,13 @@ update_label(Widget w, WidgetData *data)
static void
allocate_font(Widget w, WidgetData *data, unsigned font_idx)
{
#ifdef USE_XFT
static const unsigned attrs[4] = {
0, HL_BOLD, HL_ITALIC, HL_BOLD | HL_ITALIC
};
data->vfont[font_idx] = X11_new_font(w, attrs[font_idx], data->win_type);
#else
Display *display = XtDisplay(w);
XFontStruct *font1 = (font_idx == (font_bold | font_italic))
? data->font[font_bold]
: data->font[0];
@@ -401,6 +490,7 @@ allocate_font(Widget w, WidgetData *data, unsigned font_idx)
data->font[font_idx] = data->font_ptr[font_idx]
? data->font_ptr[font_idx]
: font1;
#endif
}
/* Free any allocated fonts */
@@ -409,11 +499,18 @@ free_fonts(Widget w, WidgetData *data)
{
Display *display = XtDisplay(w);
for (unsigned i = 0; i < 4; ++i) {
#ifdef USE_XFT
if (data->vfont[i] != NULL) {
XftFontClose(display, data->vfont[i]);
}
data->vfont[i] = NULL;
#else
if (data->font_ptr[i] != NULL) {
XFreeFont(display, data->font_ptr[i]);
}
data->font[i] = NULL;
data->font_ptr[i] = NULL;
#endif
}
}
+1 -1
View File
@@ -1362,7 +1362,7 @@ menu_create_entries(struct xwindow *wp, struct menu *curr_menu)
? commandWidgetClass
: labelWidgetClass,
wp->w, args, num_args);
X11_wrap_widget(curr->w);
X11_wrap_widget(curr->w, NHW_MENU);
X11_set_attrs(curr->w, 0x1 << attr);
if (canpick)
+2 -2
View File
@@ -2274,7 +2274,7 @@ create_widget(Widget parent, struct X_status_value *sv, int sv_index)
: "dlevel",
labelWidgetClass, parent,
args, num_args);
X11_wrap_widget(sv->w);
X11_wrap_widget(sv->w, NHW_STATUS);
break;
case SV_NAME: {
char buf[BUFSZ];
@@ -2311,7 +2311,7 @@ create_widget(Widget parent, struct X_status_value *sv, int sv_index)
XtSetArg(args[num_args], XtNinternalHeight, 0); num_args++;
sv->w = XtCreateManagedWidget(sv->name, labelWidgetClass, parent,
args, num_args);
X11_wrap_widget(sv->w);
X11_wrap_widget(sv->w, NHW_STATUS);
break;
}
default:
+2 -2
View File
@@ -57,7 +57,7 @@ create_value(Widget parent, const char *name_value)
num_args++;
name =
XtCreateManagedWidget(WNAME, labelWidgetClass, form, args, num_args);
X11_wrap_widget(name);
X11_wrap_widget(name, NHW_STATUS);
num_args = 0;
XtSetArg(args[num_args], XtNjustify, XtJustifyRight);
@@ -70,7 +70,7 @@ create_value(Widget parent, const char *name_value)
num_args++;
Widget value = XtCreateManagedWidget(WVALUE, labelWidgetClass, form, args,
num_args);
X11_wrap_widget(value);
X11_wrap_widget(value, NHW_STATUS);
return form;
}