ISO-10646 XFont 编码问题

问题描述 投票:0回答:2

我正在尝试在我的

ISO-10646
程序中使用
X Window
固定字体。它必须支持英语、俄语和希腊字母,但事实并非如此。在
xfontsel
窗口中一切正常,但在我的程序中只有英文显示正确。使用像
g++ -fexec-charset=ISO-10646 ...
g++ -finput-charset=ISO-10646 ...
这样的东西没有帮助。我该如何解决?


测试应用程序窗口截图:


xfontsel 窗口截图:


测试应用程序代码:

#include <X11/StringDefs.h>
#include <X11/Xaw/Command.h>

int main(int argc, char **argv) {
    Widget widget = XtInitialize(argv[0], "simple", NULL, 0, &argc, argv);
    XtVaCreateManagedWidget(
        "English Русский ελληνικά", labelWidgetClass, widget,
        XtNfont, XLoadQueryFont(XtDisplay(widget),
            "-Misc-Fixed-Medium-R-Normal--20-200-75-75-C-100-ISO10646-1"
        ), XtNwidth, 500, XtNheight, 100, NULL
    );
    XtRealizeWidget(widget);
    XtMainLoop();
}
c++ linux gcc encoding x11
2个回答
2
投票

您的程序使用 UTF-8 编码的单字节字符串,这不是 Xt/Xaw 所期望的。

-fexec-charset
没有任何帮助。

使用纯 Xlib(无工具包),您可以使用

Xutf8DrawString
和朋友,但 Xt 和 Xaw 没有提供。

Xaw 理论上支持将

XtNencoding
设置为
XawTextEncodingChar2b
的标签的 2 字节编码,但我永远无法使其与 UTF-16 一起使用。

    XChar2b lbl[] = { {0x04, 0x40}, {0x04, 0x43},
                      {0x04, 0x41}, {0x04, 0x41},
                      {0x04, 0x3a}, {0x04, 0x38},
                      {0x04, 0x39}, {0, 0}};

    XtVaCreateManagedWidget(
    "w00t", labelWidgetClass, widget,
    XtNfont, XLoadQueryFont(XtDisplay(widget),
        "-Misc-Fixed-Medium-R-Normal--20-200-75-75-C-100-ISO10646-1"
    ), XtNwidth, 500, XtNheight, 100, 
    XtNencoding, XawTextEncodingChar2b,
    XtNlabel, lbl,
    NULL
);

这个特定的字符串有效。我希望你能弄清楚如何生成任意标签。但是,高位或低位的空字节会终止字符串,因此无法使用此方法显示英文文本。

也许我机器上的 Xaw 副本不是最新的。 here 有一个补丁应该可以使它工作,但我不知道它是否应用于此副本,并且懒得从源代码构建补丁版本。如果您想动态链接分发代码,也许您不应该依赖它,因为并非每台机器都有最新的 Xaw 库。这个补丁是在 2014 年制作的。

我的建议是不要依赖 Xaw 的 i18n 能力。使用带有

Xutf8DrawString
的原始 X11,或现代工具包,如 Qt 或 Gtk 或 FLTK 或 wxWidgets,它们都应该与 UTF-8 无缝配合。作为最后的手段,根据需要子类化 Xaw 小部件并使它们与
Xutf8DrawString
一起工作。

更新 我已经检查了 Gentoo ebuild 的源代码,它应该是最新的。那里没有打补丁,到处都是

strlen
XChar2b
不起作用。一个典型的 Xaw 代码片段:

len = strlen(label);
...
if (len) {
    if (w->label.encoding)
        XDrawString16(XtDisplay(gw), XtWindow(gw), gc,
              w->label.label_x, y, (XChar2b *)label, len / 2);
    else
        XDrawString(XtDisplay(gw), XtWindow(gw), gc,
              w->label.label_x, y, label, len);
}

很明显,这不可能有任何正确工作的希望。


1
投票

晚了,不过:添加

#include <locale.h>
,并在创建小部件之前调用
setlocale(LC_CTYPE, ""); XtSetLanguageProc(NULL, NULL, NULL);
,并添加资源
XtNinternational, True
.

/*  $CC -o font font.c -lXaw3d -lXt -lX11   */
#include <X11/StringDefs.h>
#include <X11/Xaw/Command.h>
#include <locale.h>

int main(int argc, char **argv) {
    Widget widget = XtInitialize(argv[0], "simple", NULL, 0, &argc, argv);
    setlocale(LC_CTYPE,"");
    XtSetLanguageProc(NULL, NULL, NULL);
    XtVaCreateManagedWidget(
        "English Русский ελληνικά", labelWidgetClass, widget,
        XtNfont, XLoadQueryFont(XtDisplay(widget),
            "-Misc-Fixed-Medium-R-Normal--20-200-75-75-C-100-ISO10646-1"
        ), XtNwidth, 500, XtNheight, 100,
        XtNinternational, True,
        NULL
    );
    XtRealizeWidget(widget);
    XtMainLoop();
}
© www.soinside.com 2019 - 2024. All rights reserved.