Curses - 某些表情符号(标志)使终端输出变形
Curses - Certain emoji (flags) deform terminal output
当我将某些表情符号(特别是标志)输出到 curses 的子窗口时,它会变形输出,即使对于该子窗口之外的输出也是如此。
运行:
import curses
def draw_screen(stdscr):
event = 0
stdscr.clear()
stdscr.refresh()
while (event != ord('q')):
emojis = ["", "", ""]
# emojis = ["", "", ""]
for i, emoji in enumerate(emojis):
box1 = stdscr.subwin(11, 11, 0, i*12)
box1.box()
box1.addstr(0, 4, emoji)
event = stdscr.getch()
if __name__ == "__main__":
curses.wrapper(draw_screen)
产生:
如果你只为红心切换表情符号,效果很好:
我知道旗帜表情符号是一系列区域指示符号,但我认为这应该有效,但我不确定如何修复它。
我已经在 Mac OS 10.13 和 10.14 的 iTerm 和终端中对此进行了测试。
(我还注意到其他一些多点表情符号 () 在原始 Python 中打印得很好,但在 curses 中被分成两个单独的表情符号来组成它们。我不确定这是不是相关。)
ncurses 使用操作系统的 wcwidth
函数来确定字符的显示宽度。 Terminal.app 假设 U+1F1FA 和 U+1F1F8 使用两列,而 wcwidth
似乎表示它们各只有一列。绿心 U+1F49A 被 wcwidth
和 Terminal.app 视为双倍宽度。您可以通过在 emoji 符号之前和之后附加一个字符来看到这一点:在 ncurses 被误导的地方,结果显示显示重叠的字符。
直到 Unicode 9 (2016),根据 Unicode 的 EastAsianWidth 文件,这些特定代码都是 "neutral width"。 Unicode 技术报告 #11
Unicode 字符 属性 "East Asian Width" (从 1999 年开始)暗示(从未提供明确的定义)"neutral width" 字符的实际宽度取决于上下文,即,如果它们与双角字符一起使用时,它们应被视为双角字符。例如,它说
Narrow (and neutral) characters always map to half-width characters in the mixed-width set
但仅根据 "full-width"(两列)和 "narrow-width"(一列)字符的混合来指代 "mixed-width"。
通常 wcwidth
函数(MacOS 可能也不例外)returns 忽略区域设置的给定代码点的相同宽度。
在Unicode 8中,这些是相关行(值的范围):
1F1E6..1F1FF;N # So [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z
1F400..1F579;N # So [378] RAT..JOYSTICK
在Unicode 9中,U+1F49A是"full width",但另外两个是中性的:
1F1E6..1F1FF;N # So [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z
1F442..1F4FC;W # So [187] EAR..VIDEOCASSETTE
我没有看到那些后来通过 Unicode 12(当前)发生了变化。
鉴于所有这些,它看起来像是字体 and/or wcwidth 中的一个错误,它是由惯性延续的(在 Apple 开始制作 之前你无能为力) wcwidth
同意它的字体)。
顺便说一下,您可能会发现 Proposal on use of ZERO WIDTH JOINER (ZWJ) between two Regional Indicator Symbols 与问题相关。
当我将某些表情符号(特别是标志)输出到 curses 的子窗口时,它会变形输出,即使对于该子窗口之外的输出也是如此。
运行:
import curses
def draw_screen(stdscr):
event = 0
stdscr.clear()
stdscr.refresh()
while (event != ord('q')):
emojis = ["", "", ""]
# emojis = ["", "", ""]
for i, emoji in enumerate(emojis):
box1 = stdscr.subwin(11, 11, 0, i*12)
box1.box()
box1.addstr(0, 4, emoji)
event = stdscr.getch()
if __name__ == "__main__":
curses.wrapper(draw_screen)
产生:
如果你只为红心切换表情符号,效果很好:
我知道旗帜表情符号是一系列区域指示符号,但我认为这应该有效,但我不确定如何修复它。
我已经在 Mac OS 10.13 和 10.14 的 iTerm 和终端中对此进行了测试。
(我还注意到其他一些多点表情符号 () 在原始 Python 中打印得很好,但在 curses 中被分成两个单独的表情符号来组成它们。我不确定这是不是相关。)
ncurses 使用操作系统的 wcwidth
函数来确定字符的显示宽度。 Terminal.app 假设 U+1F1FA 和 U+1F1F8 使用两列,而 wcwidth
似乎表示它们各只有一列。绿心 U+1F49A 被 wcwidth
和 Terminal.app 视为双倍宽度。您可以通过在 emoji 符号之前和之后附加一个字符来看到这一点:在 ncurses 被误导的地方,结果显示显示重叠的字符。
直到 Unicode 9 (2016),根据 Unicode 的 EastAsianWidth 文件,这些特定代码都是 "neutral width"。 Unicode 技术报告 #11 Unicode 字符 属性 "East Asian Width" (从 1999 年开始)暗示(从未提供明确的定义)"neutral width" 字符的实际宽度取决于上下文,即,如果它们与双角字符一起使用时,它们应被视为双角字符。例如,它说
Narrow (and neutral) characters always map to half-width characters in the mixed-width set
但仅根据 "full-width"(两列)和 "narrow-width"(一列)字符的混合来指代 "mixed-width"。
通常 wcwidth
函数(MacOS 可能也不例外)returns 忽略区域设置的给定代码点的相同宽度。
在Unicode 8中,这些是相关行(值的范围):
1F1E6..1F1FF;N # So [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z
1F400..1F579;N # So [378] RAT..JOYSTICK
在Unicode 9中,U+1F49A是"full width",但另外两个是中性的:
1F1E6..1F1FF;N # So [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z
1F442..1F4FC;W # So [187] EAR..VIDEOCASSETTE
我没有看到那些后来通过 Unicode 12(当前)发生了变化。
鉴于所有这些,它看起来像是字体 and/or wcwidth 中的一个错误,它是由惯性延续的(在 Apple 开始制作 之前你无能为力) wcwidth
同意它的字体)。
顺便说一下,您可能会发现 Proposal on use of ZERO WIDTH JOINER (ZWJ) between two Regional Indicator Symbols 与问题相关。