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

使用PangoCairo在Gnome Shell扩展圆形中居中显示文本失败求助

Gnome Shell扩展:PangoCairo文本居中问题修复

问题分析

你的代码存在几个关键问题导致文本无法正确居中:

  1. 未恢复旋转变换:绘制进度圆弧时执行了cr.rotate(-Math.PI/2),但后续没有恢复这个旋转状态就绘制文本,导致文本被旋转90度,且坐标系方向错乱。
  2. 缺少垂直居中处理:text_show函数只计算了水平方向的偏移,没有考虑文本的垂直高度,导致文本在垂直方向偏离圆心。
  3. 像素尺寸与缩放坐标系不兼容:画布已通过cr.scale(width, height)做了缩放,get_pixel_size()获取的是实际像素值,直接用于缩放后的坐标系计算偏移会导致位置错误,应使用Pango的逻辑尺寸转换为用户坐标系。
  4. 多余的画笔移动:text_show末尾的cr.relMoveTo(w / 2, 0)属于无效操作,会干扰画笔位置但不影响文本显示。

修改后的代码

draw_stuff(canvas, cr, width, height) {
    cr.setSourceRGBA(1,1,1,0.2); 
    cr.save();
    cr.setOperator(Cairo.Operator.CLEAR);
    cr.paint();        
    cr.restore();      
    cr.setOperator(Cairo.Operator.OVER);       
    cr.scale(width, height);       
    cr.setLineCap(Cairo.LineCap.BUTT);                 
    cr.setLineWidth(0.08);         
    cr.translate(0.5, 0.5);        
    // 绘制外圈
    cr.arc(0, 0, 0.4, 0, Math.PI * 2);         
    cr.stroke();               
    // 绘制进度弧:保存旋转前状态,旋转后绘制,然后恢复
    cr.save();
    cr.setSourceRGBA(1,1,1,0.8);        
    cr.rotate(-Math.PI/2);      
    cr.arc(0,0, 0.4, 0, this.currentR /100 * 2 * Math.PI);
    cr.stroke();                
    cr.restore(); // 恢复旋转,保证后续绘制在原始坐标系
    // 绘制内圈
    cr.setSourceRGBA(1,1,1,0.9);        
    cr.arc(0,0, 0.25, 0, 2 * Math.PI);         
    cr.fill();          
    // 绘制文本
    cr.moveTo(0, 0);    
    cr.setSourceRGBA(0,0,0,0.9);    
    this.text_show(cr, "WoW");          
    return true; 
}

update() { 
    this.currentR = 60;
    // 注意:不要每次update都重复连接draw信号,应该在初始化时连接一次
    // this._canvas.connect("draw", this.draw_stuff.bind(this)); 
    this._canvas.invalidate();
}

text_show(cr, showtext, font = "DejaVuSerif Bold 16") {
    let pl = PangoCairo.create_layout(cr);
    pl.set_text(showtext, -1);
    pl.set_font_description(Pango.FontDescription.from_string(font));
    PangoCairo.update_layout(cr, pl);
    // 获取布局的逻辑尺寸(Pango单位,1单位=1/1024像素),转换为像素
    let [w, h] = pl.get_size();
    w /= Pango.SCALE;
    h /= Pango.SCALE;
    // 转换为缩放后的坐标系偏移:获取画布缩放因子,计算居中偏移
    const scaleX = cr.getMatrix().xx;
    const scaleY = cr.getMatrix().yy;
    cr.relMoveTo(-w / (2 * scaleX), -h / (2 * scaleY));
    PangoCairo.show_layout(cr, pl);
}

关键修改说明

  • 恢复旋转状态:绘制进度弧时用save()和restore()包裹,确保后续文本绘制在未旋转的坐标系中,避免文本方向错误。
  • 垂直居中处理:新增文本高度的偏移计算-h/(2*scaleY),实现垂直方向的居中对齐。
  • 适配缩放坐标系:使用get_size()获取Pango逻辑尺寸,转换为像素后除以画布缩放因子,确保偏移量在缩放后的坐标系中精准对应。
  • 移除无效代码:删除text_show末尾多余的cr.relMoveTo(w / 2, 0),避免干扰画笔位置。
  • 优化信号连接:update函数中不要重复绑定draw信号,应在扩展初始化阶段连接一次,防止多次绑定导致重复绘制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 16:30:56