【问题标题】:Unicode Box Drawing characters not printed in Ruby未在 Ruby 中打印的 Unicode Box Drawing 字符
【发布时间】:2018-09-20 16:37:31
【问题描述】:

我用 Ruby 开发一个游戏。它使用 ncurses 绘制窗口内容并刷新屏幕。这一切都在我开发这些东西的 macOS 上运行良好。但在 Linux 上,当与来自 Ruby 或纯 C 的 ncurses 接口时,除了纯 ASCII 之外,我无法打印任何东西。

例如,我得到这个输出:

Hello, world! M-b~U~TM-b~U~PM-b~U~WM-b~U~QM-b~U~QM-b~U~ZM-b~U~PM-b~U~]M-b~U~_M-b~T~@M-b~UM-"

而不是我放入源代码的内容:

Hello, world! ╔═╗║║╚═╝╟─╢

文件编码为 UTF-8、envlocale 输出报告 LANGLC_* 变量为 en_USen_US.UTF-8 在适当的情况下。终端可以很好地打印这些字符,所以不是字体或终端模拟器设置。

Python 3 也可以正常工作。 Ruby 和 C 没有。

(在安装了libncurses5-dev 的全新 Linux Mint 19 设置上测试。)

那么,是我遗漏了一些设置,还是 Python 绑定有些特殊而我运气不佳?


它的样子

它应该看起来像这样(macOS):

但看起来确实像这样:

Python 代码

这段代码运行良好:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import locale
import curses

locale.setlocale(locale.LC_ALL, '')

stdscr = curses.initscr()
curses.noecho()
curses.cbreak()
stdscr.addstr(0, 0, "╔═╗║║╚═╝╟─╢") # dont even need .encode('UTF-8')
stdscr.refresh()
stdscr.getkey()
curses.endwin()

curses 模块的文档说明你必须从 ncurses 5 开始执行此操作:https://docs.python.org/3/library/curses.html

从 5.4 版开始,ncurses 库决定如何使用 nl_langinfo 函数解释非 ASCII 数据。这意味着您必须在应用程序中调用 locale.setlocale() 并使用系统可用的编码之一对 Unicode 字符串进行编码。

Ruby 代码

# coding: utf-8
require "curses"

Curses.init_screen
Curses.start_color
Curses.stdscr.keypad(true) # enable arrow keys
Curses.cbreak # no line buffering / immediate key input
Curses.ESCDELAY = 0
Curses.curs_set(0) # Invisible cursor
Curses.noecho # Do not print keyboard input

Curses.stdscr.addstr(STYLES[:single])
Curses.stdscr.setpos(2,0)
Curses.stdscr.addstr(%Q{╔═╗║║╚═╝╟─╢})

Curses.getch

尝试使用 ffi-ncurses gem 而不是 curses 但无济于事。输出是一样的。

C 代码

我用编译

gcc -finput-charset=UTF-8 -fexec-charset=UTF-8 -pedantic -Wall -o main main.c -lncurses

代码如下:

// Most of the code is sample code from "CURHELLO.C"
// (c) Copyright Paul Griffiths 1999

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <langinfo.h>
#include <locale.h>
#include <ncurses.h>

int main(void) {

    // Here I tried to copy what Python is doing:
    setlocale(LC_ALL, ""); // Also tried "C.UTF-8", "en_US.UTF-8"
    nl_langinfo(CODESET);


    WINDOW * mainwin;
    if ( (mainwin = initscr()) == NULL ) {
        fprintf(stderr, "Error initialising ncurses.\n");
        exit(EXIT_FAILURE);
    }

    start_color();
    clear();
    cbreak();
    noecho();
    keypad(stdscr, TRUE);

    mvaddstr(1, 1, "Hello, world! ╔═╗║║╚═╝╟─╢");
    refresh();
    sleep(3);

    delwin(mainwin);
    endwin();
    refresh();

    return EXIT_SUCCESS;
}

编辑

通过链接到ncursesw(注意尾随的W!)使其正常工作,但它使用Ubuntu Mono(与我在OSX 上使用iTerm 尝试过的字体相同)在Linux 上以两倍的文本宽度显示特殊字符.

【问题讨论】:

  • 将 C 代码与ncursesw 链接起来,它就可以工作了。 (虽然 ncursesw 为宽字符添加了新的类型和接口,但它也为标准的 ncurses 函数添加了 UTF-8 多字节支持。)
  • 此外,Ruby 应该更喜欢 ncursesw 而不是 ncurses,因此您可能没有安装 ncursesw 包。该库由 Debian、Ubuntu、Mint 上的 libncursesw5 提供(您可能错过了这一点)。如果您还想尝试 C 中 ncursesw 中的其他接口,请同时安装 libncursesw5-dev 包。最后推荐大家使用gcc -Wall -O2 $(pkg-config --cflags ncursesw) main.c $(pkg-config --libs ncursesw) -o main编译C程序。
  • 我刚刚检查过,并注意到块元素字符,如 在 Ubuntu Monospace 中不是等宽的、Oxygen Mono、Noto Mono 或 Linux Libertine Mono O 字体:即使它们声称是等宽字体,但对于块元素来说并非如此!在我的系统上,Nimbus Mono L、Monospace、Liberation Mono、FreeMono、DejaVu Sans Mono、Bitstream Vera Sans Mono 和 Andale Mono 字体似乎具有适当的等宽字形,即使对于 Box Drawing 和 Block Elements,我建议您使用其中之一代替字体。 (并在您的文档中提及问题和字体!)
  • 您不能从终端内运行的程序更改字体;您必须指示用户更改它。对于 gnome-terminal,选择 Edit,然后选择 Profile preferences,然后选择 General 选项卡,选中 Custom font 复选框,然后然后使用复选框右侧的按钮选择字体。在 mate-terminal 中,它位于同一个选项卡中,但您需要取消选中 使用系统字体 才能选择字体。我从未使用过不允许我选择字体的 X 终端模拟器。
  • 尝试在终端中运行printf '0123456789012345678\n╔═╗║║╚═╝╟─╢▌▙▚█▞▟▐|\n',看看是否真的是字体问题。如果你问我,我会改用 SDL 或 GTK+3.0,使用 SVG 格式的图块。

标签: python c ruby linux ncurses


【解决方案1】:

其实这应该是几个问题,但最近的一个问题是如何将字符显示为双角。

屏幕截图与给定的示例程序不匹配。这仅绘制了几个示例字符,而屏幕截图显示了框。

但是,与区域设置表相比,特定的线条绘制字符可能是问题所在(并且取决于所使用的实际程序)。那是因为这些代码是ambiguous width(参见U+2550)。该标准由实施者决定将它们视为单宽还是双宽。并非所有人都同意实际宽度。

如果这是bug report,我会得到实际的程序源来测试,但怀疑问题出在Ruby。

【讨论】:

  • 啊,现在我明白了。一些等宽字体,如 Ubuntu Mono、Oxygen Mono、Noto Mono 和 Linux Libertine Mono O 字体对 Block Elements 使用不同的宽度,因为它们对 Box Drawing 字形使用不同的宽度,因为 Unicode 板上的某些人认为其中一些可能在某些东方使用亚洲字体,所以最好给每个人拧一下等宽宽度,所以字体对于方框图和块元素基本上没用。委员会设计...
  • 同意 - 使使用这些字符变得更加困难,因为没有一个委员会考虑过如何使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
  • 2013-02-03
  • 2017-12-06
  • 1970-01-01
  • 2017-02-16
相关资源
最近更新 更多