すべてのウインドウにはなにかを表示させようとするとき、それぞれグラフィッ クスコンテキストと呼ばれる情報が必要となります。なにかを書くときの色 (背景色とペンの色)、線の太さや実線か点線かなどの形状、塗りつぶしをする ときの境界の色や塗りつぶすパターン、文字のフォントや大きさなどですが、 通常はデフォールト値が使われます。それぞれのパラメータはリソースと呼ば れ、システムの標準値やユーザの好みの値(.Xdefault sというファイルに書か れる。)がデフォールトとして使われますがアプリケーションで指定すること が出来ます。いずれにせよ、まず現在のデフォールトのコピーを元にして新し いグラフィックスコンテキストを作り、そのパラメータを適当に設定して描画 に用います。
GC gc; /* 上の例題ではXMapWindowの後、XFlushの前に以下の文を挿入 */ gc = XCreateGC( display, window, 0, 0 ); XDrawLine( display, window, gc, 10, 100, 490, 300 );
Xlibの描画関数は、ディスプレイ、その上にある描画可能なウインドウ(ドロ ウアブルと呼ばれる)とグラフィックスコンテキストを与えて初めて絵が描け ます。途中から線の色を変えたり文字の大きさを変えたりするのは、そこでグ ラフィックスコンテキストを変更することによって可能になるのです。また、 あるウインドウの子ウインドウがつくられたとき、その子ウインドウは親のグ ラフィックスコンテキストを継承します。
親がボタンで子がメニューというように形は違う物でもグラフィックスコン テキストは同じになります。黄色いボタンを押すとデフォールトでは黄色いメ ニューが表示されます。このように形は違うけれども表示物として同じ物には グラフィックスコンテキストは継承されます。グラフィックスコンテキストは 抽象的な描画物を表すクラスであり、ボタンやメニューはそれらの継承クラス です。どちらも基本クラスであるグラフィックスコンテキストを継承しますが 形は全然違います。表示されるボタンは普通黄色ですが、個別に赤い色を指定 できます。それぞれのボタンはインスタンスであり各々のインスタンスに属性 の設定は可能です。ボタンクラスは黄色ですが特定のボタンクラスインスタン スを赤くすることが出来るわけです。これらはオブジェクト指向の非常に原始 的な概念を表しています。
よく使われるコンテキストについて見ていきましょう。まず描画に使われる 色を選びたいですね。色の扱いは次のようになります。結構複雑です。色その ものはlong intで表され、ピクセル値と呼ばれます。問題は日常で使う赤とか 緑という概念と実際のピクセル値の間には固定的な関係はないということです。 なぜならXサーバは次から次に来る要求に応じてパレットと呼ばれる色を表示 するための仕組みの内容を切り替えて使っています。使われなくなった色の変 わりに新しい色のデータを書き込んで使うからです。そのために「緑」という 情報を現在サーバが持っている情報と突き合わせなければなりません。まずCo lormap構造体で表される色のテーブルをもらいます。
Colormap colormap; XColor thiscolor, exactcolor; colormap = DefaultColormap( display, screen ); XAllocNamedColor( display, colormap, "green", & thiscolor, & exactcolor );
ここでXColor構造体は
typedef struct { unsigned long pixel; unsigned short red, green, blue; char flags; char pad; } XColor;
という構造を持っています。上の例ではthiscolor.pixelに得られたピクセル 値が入っています。RGBの3原色で色を指定したいときもあると思います。 XColorにメンバーがありますね。次のようになります。強さの範囲は0から 65535までの値を取ります。
thiscolor.red = 0; thiscolor.green = 65535; thiscolor.blue = 0; XAllocColor( display, colormap, & thiscolor );
この場合も結果のピクセル値はthiscolor.pixelに返されます。
得られたピクセル値を使ってグラフィックコンテクストを変更しましょう。 Foregroundがペンの色にあたります。
XSetForeground( display, gc, thiscolor.pixel );
背景色も同様に
XSetBackground( display, gc, pixel );
線を引く場合、その幅や点々、折れ線の角の処理などを設定したくなります。
XSetDashes( display, gc, dash_offset, dash_list, n ); XSetLineAttributes( display, gc, line_width, line_style, cap_style, join_style );
使い方はmanで調べてください。同様に塗りつぶしも
XSetFillRule( display, gc, fill_rule ); XSetFillStyle( display, gc, fill_style ); XSetTile( display, gc, tile ); /* Pixmap tile */
などがあります。