You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从XftFont获取XFontStruct?X11可缩放时钟字体问题

解决方案:用Xft实现可缩放的X11时钟文本绘制

1. 修复XftDrawString的BadPicture错误

BadPicture错误几乎都是因为XftDraw对象创建不规范导致的。正确的创建方式需要和窗口的Visual、Colormap严格匹配:

// 基于当前窗口的默认Visual和Colormap创建XftDraw
XftDraw* xft_draw = XftDrawCreate(dpy, window, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen));

绘制完成后务必销毁资源:

XftDrawDestroy(xft_draw);

不要手动创建Picture对象混用,Xft的绘图上下文需要单独管理。

2. 理清Xlib与Xft的绘图边界

不要在同一段绘图逻辑里混合Xlib的XSetForeground、XDrawString和Xft函数。建议拆分职责:

  • 用Xlib绘制钟面的线条、指针等矢量图形
  • 用Xft专门处理文本渲染,单独维护Xft的颜色和绘图对象

文本绘制示例代码

// 定义文本颜色(以白色为例)
XftColor xft_color;
XRenderColor render_color = {0xffff, 0xffff, 0xffff, 0xffff};
XftColorAllocValue(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), &render_color, &xft_color);

// 创建Xft绘图上下文
XftDraw* draw = XftDrawCreate(dpy, window, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen));

// 动态加载对应字号的字体(字号可根据窗口尺寸计算)
int font_size = MIN(window_width, window_height) / 12;
char font_spec[64];
snprintf(font_spec, sizeof(font_spec), "Sans:size=%d", font_size);
XftFont* font = XftFontOpenName(dpy, screen, font_spec);

// 计算文本位置(以数字12为例,居中顶部)
XftFontExtents* extents = XftFontExtents(dpy, font);
int x_pos = (window_width - font->max_advance_width) / 2;
int y_pos = extents->max_height; // 基线位置,可根据需求微调

// 绘制文本
XftDrawStringUtf8(draw, &xft_color, font, x_pos, y_pos, (FcChar8*)"12", strlen("12"));

// 清理资源
XftFontClose(dpy, font);
XftDrawDestroy(draw);
XftColorFree(dpy, DefaultVisual(dpy, screen), DefaultColormap(dpy, screen), &xft_color);

3. 关于XftFont获取XFontStruct的说明

现代Xft库(2.x及以上)已经完全基于FreeType和XRender实现,不再依赖Xlib的传统字体系统,因此XftFont结构中不再包含直接的XFontStruct指针——xft(3)手册中的描述是针对旧版Xft 1.x的,现已过时。

如果坚持要用Xlib的XDrawString绘制缩放文本,有两个替代方向:

  • 使用XCreateFontSet加载可缩放字体(如Type1/TrueType),但灵活性远不如Xft
  • 通过XRender扩展手动渲染FreeType glyph,实现复杂度高,性价比低

4. 动态适配窗口大小的字号计算

根据窗口的最小边尺寸动态调整字号,保证数字始终适配钟面:

XWindowAttributes attr;
XGetWindowAttributes(dpy, window, &attr);
int min_edge = MIN(attr.width, attr.height);
int font_size = min_edge / 12; // 可根据视觉效果调整比例

内容的提问来源于stack exchange,提问作者Lenik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 03:51:19