FLTK中FL_Widget使用自定义字体时垂直对齐如何调整至默认效果
问题原因
FLTK 1.3.x 对控件标签的默认垂直对齐逻辑是基于全局默认字体的字形参数(上升高度ascent、下降高度descent)计算的,替换自定义字体后,不同字体的字形metrics存在差异,就会出现垂直对齐偏移的情况,该表现属于FLTK的已知特性,并非平台独有问题。
解决方案
以下提供两种可直接落地的实现方案:
方案1:单控件标签偏移调整(推荐,无需修改控件继承逻辑)
通过Fl::font_extents分别获取默认字体和自定义字体的字形参数,计算差值后用label_yoffset方法调整目标控件的标签垂直偏移即可。
修改后的示例代码如下:
#include <FL/Fl.H> #include <FL/Fl_Window.H> #include <FL/Fl_Box.H> int main(int argc, char **argv) { Fl_Window* G_win; G_win = new Fl_Window(300,100,"The font test"); Fl_Box* A = new Fl_Box(30,30,110,50,"The font TEST."); A->box(FL_UP_BOX); int i = 0; int k = Fl::set_fonts(i ? (i>1 ? "*" : 0) : "-*"); Fl_Box* B = new Fl_Box(145,30,110,50,"The font TEST."); B->box(FL_UP_BOX); int custom_font_id = 419; B->labelfont(custom_font_id); // 新增对齐调整代码 int default_asc, default_desc, default_lead; int custom_asc, custom_desc, custom_lead; // 获取默认字体(FL_HELVETICA为FLTK默认无衬线字体)的字形参数 Fl::font_extents(FL_HELVETICA, B->labelsize(), &default_asc, &default_desc, &default_lead); // 获取自定义字体的字形参数 Fl::font_extents(custom_font_id, B->labelsize(), &custom_asc, &custom_desc, &custom_lead); // 计算垂直偏移量调整对齐 B->label_yoffset(default_asc - custom_asc); G_win->show(); return Fl::run(); }
方案2:全局自定义对齐逻辑(适合多控件统一使用自定义字体的场景)
如果项目中大量控件都需要使用自定义字体,可继承Fl_Box(或其他需要的控件基类),重载draw()方法,自行计算文本基线位置进行绘制,完全控制对齐逻辑:
class CustomFontBox : public Fl_Box { public: CustomFontBox(int x, int y, int w, int h, const char* l = 0) : Fl_Box(x,y,w,h,l) {} protected: void draw() override { // 先绘制盒子边框 draw_box(); // 计算文本位置,以默认字体的对齐规则为基准 int default_asc, default_desc, default_lead; int custom_asc, custom_desc, custom_lead; Fl::font_extents(FL_HELVETICA, labelsize(), &default_asc, &default_desc, &default_lead); Fl::font_extents(labelfont(), labelsize(), &custom_asc, &custom_desc, &custom_lead); int text_x = x() + (w() - fl_width(label()))/2; int text_y = y() + (h() - (default_asc + default_desc))/2 + default_asc; // 绘制文本 fl_font(labelfont(), labelsize()); fl_color(labelcolor()); fl_draw(label(), text_x, text_y); } };
补充说明
- 如果更换自定义字体的字号,需要重新计算偏移量。
- 可通过
Fl::get_font_name方法验证传入的字体ID对应的字体是否正确,避免字体加载失败导致的额外偏移。
内容的提问来源于stack exchange,提问作者Eddymage
相关产品推荐
相关产品推荐

