我怎么知道一个字符是否适合网格,如果不适合,它需要多少空间?

How can I know if a character will fit into the grid, and if it won't, how many spaces it needs?

使用 ncurses,我如何知道某个字符是否适合网格?我假设这是依赖于字体的,我完全不确定该怎么做。

所以在上面的例子中,我要找的函数是:

grid_spaces_per_char(L"字") => 2
grid_spaces_per_char(L"G") => 1
grid_spaces_per_char(L"") => 2
grid_spaces_per_char(L"Q") => 1
grid_spaces_per_char(L"。") => 2

我需要知道这一点,以便我可以在支持 UTF-8 的 C++ Slack ncurses 应用程序中实现自动换行。

如果单独使用 ncurses 无法完成,我应该怎么做才能获取此信息?

我自己通过使用一些不同的关键字找到了答案 -- 答案是使用在 wchar.h 中找到的 wcswidthwcwidth

有一些注意事项,例如,Windows 不包含此功能,有时它可能会过时。更多注意事项解释 here and here

wcwidth 只是解决方案的一部分:ncurses 将控制字符(空格除外)扩展为两个字符。 "easy" 方法是将字符写到不显示的 window 上,并使用位置 before/after 找到 ncurses 在可见 (refreshed) windows。 window 可以在不影响屏幕显示的情况下创建、用于工作区和删除。

Lynx

中使用了该技术
    /*
     * Determine the number of cells the given string would take up on the screen,
     * limited (in the case of wide characters) by the maxCells parameter.
     *
     * If the returnCellNum parameter is TRUE, return the number of cells;
     * otherwise, return the length (limited by the len parameter) of the prefix of
     * the string that fits in maxCells cells.
     */

以及 ncurses-examples 程序 view,评论

    /*
     * Use the curses library for rendering, including tab-conversion.  This
     * will not make the resulting array's indices correspond to column for
     * lines containing double-width cells because the "in_wch" functions will
     * ignore the skipped cells.  Use pads for that sort of thing.
     */

顺便说一句:

  • wcwidth在不同的系统上给出不同的结果,它可能与终端上显示的实际上不对应。这是引入标准的方式的限制,而不是在另一个之上构建标准,存在相互矛盾的解释、不完整的文档等。

  • 它也应该(但显然很少)依赖于语言环境,因为某些字符在不同的语言环境中具有不同的宽度。在 xterm 中,这两个问题都与 line-drawing

  • 一起出现
    /*
     * Solaris 10 wcwidth() returns "2" for all of the line-drawing (page
     * 0x2500) and most of the geometric shapes (a few are excluded, just
     * to make it more difficult to use).  Do a sanity check to avoid using
     * it.
     */

soft-hyphens

        /*
         * Regarding the soft-hyphen aberration, see
         * http://archives.miloush.net/michkap/archive/2006/09/02/736881.html
         */