与cairo, pango, libvte, xfce4-terminal和gnome-terminal的接触

GTK+是GNOME桌面环境的核心图形库‌‌,它俩的关系像GDI和Windows的关系(不讨论GDI+和WPF)。

GTK+(GIMP Toolkit)最初是为GIMP图像处理软件开发的

VTE,即Virtual TErminal widget,是GTK+的一部分。widget像Windows的Common Control (文本框、列表框等控件)。

xfce4-terminal和gnome-terminal都调用VTE,都是在外面包了一层。

在我高度精减的XFCE环境下,apt install gnome-terminal:

 新安装了 88 个软件包,要卸载 0 个软件包,有 15 个软件包未被升级。
 需要下载 65.1 MB 的归档。解压缩后会消耗 269 MB 的额外空间。


在xfce4-terminal里,终端里的文字紧贴着窗口边框,我觉得不爽,于是下载了源码来改,踩了的坑如下:

当屏幕上有n个xfce4-terminal窗口时,进程只有1个。后启动的通过D-Bus要求先启动的新建窗口:

main.c里 if (terminal_gdbus_invoke_launch (nargc, nargv, &error) return EXIT_SUCCESS;

所以无论你怎么修改源码,./xfce4-terminal,都看不到变化。精确地说,在它之前exit()可以。

于是在xterm里编辑源码和运行xfce4-terminal

D-Bus(Desktop Bus)旨在为Linux桌面环境提供标准化的进程间通信(IPC)机制‌。它于2007年发布后被集成到Qt、GNOME、KDE等桌面环境,取代了CORBA、DCOP等。


terminal_screen_draw()看起来非常像是绘制字符串的,但是:

if (G_LIKELY (background_mode != TERMINAL_BACKGROUND_IMAGE)) return FALSE;

如果没有使用背景图片,该函数直接返回,绘制是VTE干的。

xfce4-terminal和gnome-terminal这俩包工头并没有不断地读终端的字符串输出并绘制。光标都是VTE画的。

一个UI东施效颦kernel,也玩likely? 而且Profile-Guided Optimization好像没啥用。

先修改terminal-screen.c加了点边框:

gtk_container_set_border_width (GTK_CONTAINER (screen->swin), 1); // 新增
gtk_container_add (GTK_CONTAINER (screen->swin), screen->terminal); // 原有


包 libvte-2.91-doc 在/usr/share/doc/vte-2.91/ 放了一堆.html文件。

打开index.html后,Functions里寥寥无几。打开比如method.Terminal.feed_child.html 后,才看到了Methods.

有很多method. set_有很多,但没有能设置margin的。


回到terminal_screen_draw()

cairo_save(ctx); // 新增、不加也行
cairo_translate(ctx, 2, 0); // 新增
gtk_widget_draw (screen->terminal, ctx); // 每按一下键,就重画全屏?真奢侈啊
cairo_restore (ctx); // 新增、不加也行。和save配套

文字终于往右挪了。用透明的png做背景和无图背景透明效果一样。

from PIL import Image as I
img=I.new('RGBA', (8,8), (0,0,0,0)) # 透明
img=I.new('RGBA', (8,8), (0,0,0,255)) # 黑色
img.save('bkgnd.png')

应该修改VTE的。起码可以把draw background image的部分注释掉。

static gboolean
terminal_screen_draw (GtkWidget *widget,
                      cairo_t   *cr,
                      gpointer   user_data)
{
  TerminalScreen     *screen = TERMINAL_SCREEN (user_data);
  TerminalBackground  background_mode;
  GdkPixbuf          *image;
  gint                width, height;
  cairo_surface_t    *surface;
  cairo_t            *ctx;

  terminal_return_val_if_fail (TERMINAL_IS_SCREEN (screen), FALSE);
  terminal_return_val_if_fail (VTE_IS_TERMINAL (screen->terminal), FALSE);

  g_object_get (G_OBJECT (screen->preferences), "background-mode", &background_mode, NULL);

  if (G_LIKELY (background_mode != TERMINAL_BACKGROUND_IMAGE))
    return FALSE;

  width = gtk_widget_get_allocated_width (screen->terminal);
  height = gtk_widget_get_allocated_height (screen->terminal);

#if 0
  if (screen->loader == NULL)
    screen->loader = terminal_image_loader_get ();
  image = terminal_image_loader_load (screen->loader, width, height);

  if (G_UNLIKELY (image == NULL))
    return FALSE;
#endif

  g_signal_handlers_disconnect_by_func (G_OBJECT (screen->terminal),
      G_CALLBACK (terminal_screen_draw), screen);

  cairo_save (cr);

#if 0
  /* draw background image; cairo_set_operator() allows PNG transparency */
  gdk_cairo_set_source_pixbuf (cr, image, 0, 0);
  cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
  cairo_paint (cr);
  g_object_unref (G_OBJECT (image));
#endif

  /* draw vte terminal */
  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
  ctx = cairo_create (surface);
  { GdkRGBA c;
   vte_terminal_get_color_background_for_draw(widget, &c);
   cairo_set_source_rgba(ctx, c.red, c.green, c.blue, c.alpha); }
  cairo_rectangle(ctx, 0, 0, 2, height);
  cairo_fill(ctx);
  cairo_translate(ctx, 2, 0);
  gtk_widget_draw (screen->terminal, ctx);
  cairo_set_source_surface (cr, surface, 0, 0);
  cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
  cairo_paint (cr);
  cairo_destroy (ctx);
  cairo_surface_destroy (surface);

  cairo_restore (cr);

  g_signal_connect (G_OBJECT (screen->terminal), "draw",
      G_CALLBACK (terminal_screen_draw), screen);

  return TRUE;
}
View Code

xfce4-terminal不白改:加了窗口边框,不用准备图片了,画矩形比拉伸或平铺图片快。tile: 瓦片。

Cairo 是一个功能强大的开源2D图形库,旨在为所有输出媒体生成一致的输出,并在可用时利用显示硬件加速‌。它广泛应用于操作系统界面、网页渲染、PDF和SVG等。

SVG是Scalable Vector Graphics‌的缩写,用于描述二维矢量图形‌。


为了编译VTE,只得又装build system,什么meson, ninja...

[47/209] Compiling C++ object src/libvte-2.91.so.0.7000.6.p/icu-glue.cc.o

我去;改改screen,用空格留出空白算了。哦,在draw_text_internal()里x += 2即可。


Pango是一个用于高质量渲染国际化文本的函数库,支持复杂文本布局(如双向文本排列)和多语言字体显示功能‌。它通过整合Xft、XRender等技术实现抗锯齿字体渲染,并能处理阿拉伯语、泰米尔语等复杂文字的形状特征‌。作为GTK工具包的核心组件,Pango负责文本布局和字体选择,而Cairo提供2D图形绘制功能‌。两者通过PangoCairo‌ 模块结合,实现文本与图形库的集成,例如在GTK+3等框架中依赖此模块完成文本渲染‌

Pango‌源自希腊语“πανγων”(pangōn),意为“所有角度”或“全方位”。

白人老爷们搞这个的原因可能有:崇高的精神;吃饱了没事干;良心发现对过去的掠夺不好意思;让他们忙于鼓捣泰米尔字体、词库和输入法。

posted @ 2025-11-16 23:44  华容道专家  阅读(6)  评论(0)    收藏  举报