(2005.5.15 新規作成)
[2017.5] gtk3に更新. コンパイルエラーになった箇所を修正。
[2020.12] 最新の環境で再コンパイル。
Pango は、GNOMEで使われているテキストのレイアウト・レンダリングモジュール。内部ではテキストをUnicodeで表現する。
日本語が表示できるのはアプリケーションを見ていれば分かるので、合字のある言語でも表示できるか試してみた。
タイ語で、
と表示できるか。Windows版のMozilla 1.7.7, Internet Explorer 6.0では表示できる。Linux版のMozilla, Firefoxでは表示できなかった。
この文字列はUnicodeでは次のコードからなる。2番目と3番目のコードの両方が1文字目のグリフに影響する。また、2番目のコードが表す字形の表示位置が上のほうへ回っているのが分かる。
U+0E19
THAI CHARACTER NO NU
U+0E49
THAI CHARACTER MAI THO
U+0E33
THAI CHARACTER SARA AM
[2017-05] Fedora 25, gtk3 3.22.12, pango 1.40.5 という環境で表示できるか試してみた。
ソースコード
まずは、ヘッダをincludeして、ウィンドウを閉じたときの処理を書く。Pango単体のときはともかく、通常はgtk+から使うので、gtk+のヘッダをincludeする。
C++
- #include <stdio.h>
- #include <gtk/gtk.h>
-
- int on_destroy(GtkWidget* w, GdkEvent* e, void* d)
- {
- gtk_main_quit();
- return 0;
- }
今回テストしたのは、次の文字列;
C++
- const char* str = u8"<span font_desc='IPAexMincho' size='40000'><u>日本語</u> "
- "<span>น้ำ</span>葛󠄀葛󠄁😁🇯🇵🥷🏽\U0001F441\U0000FE0F\U0000200D\U0001F5E8\U0000FE0F</span>";
- IVS (Ideographic Variation Sequence) への対応。よくある例で, 葛 U+845B に U+E0100 または U+E0101を続けます。
- 絵文字 Emoji. 吹出しの目 [
U+1F441 片目, U+FE0F バリエイションセレクタ16, U+200D ゼロ幅ジョイナ,
U+1F5E8 吹出し左, U+FE0F バリエイションセレクタ16]
- 国旗 Regional Indicator Symbols. U+1F1E6 〜 U+1F1FF を2文字続ける。Unicode 6.2 (2012年) から 2文字ペアで分割しないことが明確になった。See UAX #14: Unicode Line Breaking Algorithm. また, このために, データベースに Regional_Indicator という新しいフラグを導入するハメに。
- Skin-tone (Unicode 8.0; 2015年). Leftist (差別主義者) は何でも区別したがる。人間というただ一つの種があるのに, 細分化し、区別し、対立させる。この例では, U+1F3FD EMOJI MODIFIER FITZPATRICK TYPE-4
Pangoでは、テキストの文字の大きさ、色などを指定するのに、HTMLに似たタグでテキストをマークアップする; <span>
, <b>
, <i>
, <s>
, <sub>
, <sup>
, <u>
.
特に, <span>
の属性値で視覚効果を指定できます。font_desc
属性値でフォント名・大きさなどを与えます。
これらでマークアップした文字列を pango_parse_markup()
に渡して、プレーンテキストの文字列と、属性に分解する。下の例では, text
と attrs
に分離しています。
gtk+では、ラベルなど, ただの文字列も与えることができるようになっています。まず文字列を設定してから属性を別に追加するようになっている。属性は *_set_attributes()
で与える。
C++
- int main(int argc, char* argv[])
- {
- GtkWidget* window;
- GtkWidget* label;
-
- char* text = NULL;
- PangoAttrList* attrs = NULL;
- GError* error = NULL;
-
- gtk_init(&argc, &argv);
-
-
- if (!pango_parse_markup(str, -1, 0, &attrs, &text, NULL, &error)) {
- printf("error:%s\n", error->message);
- return 1;
- }
-
- label = gtk_label_new(text);
-
- gtk_label_set_attributes(GTK_LABEL(label), attrs);
あとは、ウィンドウを生成するだけ。
C++
- window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title(GTK_WINDOW(window), "Pangoでの表示");
-
- gtk_container_add(GTK_CONTAINER(window), label);
- gtk_container_set_border_width(GTK_CONTAINER(window), 30);
- gtk_widget_show_all(window);
-
- g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(on_destroy), NULL);
-
- gtk_main();
-
- pango_attr_list_unref(attrs);
- free(text);
- if (error) g_error_free(error);
-
- return 0;
- }
コンパイル、実行結果
次のようにしてコンパイルする。
$ gcc -Wall `pkg-config --cflags --libs pango gtk+-3.0` pango.cc -lstdc++
実行結果は、次のようになる。[2020.12] Fedora 33 で実行。IVS は未対応。HarfBuzz (hb-view コマンド) では対応しているので, Pango の問題か?
タイ語も表示できている。