使用C++更改终端字体大小

10

我正在使用C++(在Ubuntu 11.04下)做一个小项目,这个程序是基于文本的(全部在Gnome终端中)。我正在使用ncurses库更改字体颜色,但我还想在终端中打印不同大小的文本,而且用ncurses无法实现。有没有一种方法可以做到这点(也许是使用ncurses或其他库)?理想情况下,我希望它是终端无关的,但如果只能在Gnome中工作,或者仅在Ubuntu中工作,或者有其他限制,那么总比没有好。

感谢您一如既往地提供帮助。


我尝试了Keith Thompson的建议,但没能让它工作。这是我的代码:

cout << "\x1b]50;" << "10x20" << "\a" << flush;
cout << "test";

它只显示为终端偏好设置中指定的相同字体大小。我正在使用:GNOME 终端 2.32.1 如果有帮助!


你说"fun"的时候我还很感兴趣,但是一提到C++就有点被打击了。其实即使这是一个老问题,它也很有意思。C语言(我很确定C++也是一样)本身并没有字体概念,而且这只是故事的一部分(你已经提到了终端)。 - Pryftan
3个回答

7
至少对于xterm,您可以通过打印转义序列来更改当前字体。语法是ESCAPE]50;FONTNAME BEL
以下是我使用的脚本的缩写版本;我称之为xfont(真实版本有更多错误检查):
#!/usr/bin/perl

use strict;
use warnings;

print "\e]50;@ARGV\a";

我不知道哪些其他终端仿真器可以识别此序列。特别是,即使screen会话位于xterm窗口中,我发现它在screen下也无法工作。
请注意,您必须指定字体的名称"10x20""9x15"),而不是其大小。
编辑:我应该更加注意标签。以C++为例,可能是这样的:
std::cout << "\x1b]50;" << font_name << "\a" << std::flush;

更新:如果您正在使用TrueType字体,则使用xterm将无法正常工作。此外,Dúthomhas在评论中建议:

我知道这很旧,但是所有的terminfo字符串都应该使用putp() [或 tputs()]打印,即使是在C++中也是如此。

putp((std::string{"\33]50;"} + font_name + "\a").c_str());


也许 Gnome 终端不识别相同的转义序列。尝试启动一个 xterm 窗口(xterm&)并在那里尝试。运行 xlsfonts 获取可用字体列表(我的系统上有几千个)。或者运行 xlsfonts | egrep '^[0-9]+x[0-9]+$' 获取 WIDTHxHEIGHT 字体名称列表(我有其中的 14 个)。如果在 xterm 中可以工作但在 Gnome 终端中无法工作,则可能存在 Gnome 特定的解决方案。(或者可能不可能;如果 Gnome 实现了此功能,我期望它使用与 xterm 相同的语法。) - Keith Thompson
我也无法在xterm中使其工作 :/。我甚至尝试了你的perl示例:print "\e]50;10x20\a"; print "test";,在gnome和xterm中字体大小都是相同的。也许这是最近发生的变化。您在哪个操作系统/终端上运行您的xfont系统? - navr91
1
@navr91:我在Ubuntu和Cygwin上使用它,并且过去也在其他系统上使用过。嗯。在xterm窗口中按住Control键并右击,看看是否启用了“允许字体操作”。相应的X资源名称是allowFontOps - Keith Thompson
1
@navr91:明确一点,如果我描述的方法有效,它将更改整个窗口的字体大小,并可能更改窗口的大小以适应。如果您尝试在同一窗口中同时显示不同字体大小的文本,则典型的终端仿真器将不允许您这样做。 - Keith Thompson
1
我知道这很老,但所有的terminfo字符串都应该使用putp() [或tputs()]打印,即使在C++中也是如此。 putp((std::string{"\33]50;"} + font_name + "\a").c_str()); - Dúthomhas
显示剩余2条评论

1

你能做的最好的就是使用粗体字。终端模拟真实的基于文本的终端,因此不支持同时使用不同的字体。


0

ncurses不会改变字体大小,但可以使用视频属性(加粗、斜体)来操作字体中的样式。一些终端有一种文档化的方法来改变它们的字体大小,这会影响整个窗口(使其对ncurses“不可见”)。

如上所述,xterm具有设置字体的功能,该功能在XTerm控制序列中有记录,在操作系统命令部分中:

        Ps = 5 0Set Font to Pt.  These controls may be disabled
      using the allowFontOps resource.  If Pt begins with a "#",
      index in the font menu, relative (if the next character is a
      plus or minus sign) or absolute.  A number is expected but not
      required after the sign (the default is the current entry for
      relative, zero for absolute indexing).

      The same rule (plus or minus sign, optional number) is used
      when querying the font.  The remainder of Pt is ignored.

      A font can be specified after a "#" index expression, by
      adding a space and then the font specifier.

      If the TrueType Fonts menu entry is set (the renderFont
      resource), then this control sets/queries the faceName
      resource.

手册页面将faceName文档化为字体系列名称。虽然可以尝试向其中添加pixelsize属性,但可能不起作用。但是更改faceName可以解决问题(假设您已选择了TrueType字体),例如,在我的当前计算机上使用此脚本:
#!/bin/bash
setfont() {
read -p "$1:"
printf '\033]50;%s\007' "$1"
read -p "done!"
}
setfont "Bitstream Charter"
setfont "URW Gothic L"

我使用fc-list获取了这些字体名称。类似的脚本也可以用于位图字体,使用xlsfonts找到的名称。对于位图字体,有一些字体别名,例如9x1510x2012x24,但这些仅针对xlsfonts的数千个结果中的少数组合进行定义。关于此,请阅读X Logical Font Description Conventions文档。顺便说一句,这些有用的字体别名没有在任何地方系统地记录。

这只会改变字符的外观,可能不会改变大小。但是,通过阅读文档,可以使用从rxvt适应的功能,使用数字逐步浏览字体菜单上的设置。对我来说,这个脚本很有效,将字体更改为上一个,两次,下两个(返回默认值),上四个(到达设置的末尾),然后返回:

#!/bin/bash
changesize() {
read -p "$1:"
printf '\033]50;#%s\007' "$1"
read -p "done!"
}
changesize +1
changesize +1
changesize -2
changesize +4
changesize -4

由于使用了一个不在终端数据库中的控制序列,因此程序中的 coutprintf 是合适的。 对于来自终端数据库的字符串,应该使用putp,因为它们可能包含填充信息,这些信息会被 putp 解释(当直接打印到终端时将没有用处)。 相反,某些随机的控制序列可能看起来像是可能会使putp混淆的东西。

填充已在terminfo(5)中记录。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接