XGCValues(3) グラフィックスコンテクストの生成・解放関数と、グラフィックスコンテクスト構造体

Other Alias

XCreateGC, XCopyGC, XChangeGC, XGetGCValues, XFreeGC, XGContextFromGC

書式

GC XCreateGC(display, d, valuemask, values)

      Display *display;

      Drawable d;

      unsigned long valuemask;

      XGCValues *values;

XCopyGC(display, src, valuemask, dest)

      Display *display;

      GC srcdest;

      unsigned long valuemask;

XChangeGC(display, gc, valuemask, values)

      Display *display;

      GC gc;

      unsigned long valuemask;

      XGCValues *values;

Status XGetGCValues(display, gc, valuemask, values_return)

      Display *display;

      GC gc;

      unsigned long valuemask;

      XGCValues *values_return;

XFreeGC(display, gc)

      Display *display;

      GC gc;

GContext XGContextFromGC(gc)

      GC gc;

引き数

d
ドロウアブルを指定する。
dest
対象となる GC を指定する。
display
X サーバへの接続を指定する。
gc
GC を指定する。
src
元の GC のコンポーネントを指定する。
valuemask
GC のコンポーネントのうち、設定・コピー・変更されるもの、あるいは値が 返されるものを指定する。 この引き数は、GC コンポーネントの有効なマスクビットの 0 個以上に対して、 ビットごとの論理和をとったものである。
values
引き数 valuemask で指定したコンポーネントの値を指定する。
values_return
指定した XGCValues 構造体内の GC 値が返される。

説明

関数 XCreateGC はグラフィックスコンテクストを生成して、GC を返す。 生成された GC は指定したドロウアブルと同じルートウィンドウ、深さを持つ 任意の描画対象のドロウアブルと共に用いることができる。 他のドロウアブルと共に使った場合には、エラー BadMatch となる。

XCreateGC はエラー BadAlloc, BadDrawable, BadFont, BadMatch, BadPixmap, BadValue を起こすことがある。

関数 XCopyGC はコピー元の GC の指定したコンポーネントをコピー先の GC にコピーする。 コピー元とコピー先の GC は、ルートウィンドウと深さが同じでなければならな い。そうでなければ、エラー BadMatch となる。 valuemask は XCreateGC の場合と同じく、どのコンポーネントをコピーするかを指定する。

XCopyGC はエラー BadAlloc, BadGC, BadMatch を起こすことがある。

関数 XChangeGC は、指定したGCの valuemask で指定したコンポーネントを変更する。 引き数 values には設定する値を与える。 この関数の値と制限は XCreateGC の場合と同じである。 clip-mask の変更は、そのコンテクストに対する以前の XSetClipRectangles を上書きする。 dash-offset や dash-list の変更は、そのコンテクストに対する以前の XSetDashes を上書きする。 コンポーネントが確認、変更される順序は、サーバに依存する。 エラーが発生した場合、コンポーネントの一部はすでに変更されているかもし れない。

XChangeGC はエラー BadAlloc, BadFont, BadGC, BadMatch, BadPixmap, BadValue を起こすことがある。

関数 XGetGCValues は、指定した GC の指定した valuemask で指定されるコンポーネントを返す。 valuemask が正しい GC マスクビットの集合 (GCFunction, GCPlaneMask, GCForeground, GCBackground, GCLineWidth, GCLineStyle, GCCapStyle, GCJoinStyle, GCFillStyle, GCFillRule, GCTile, GCStipple, GCTileStipXOrigin, GCTileStipYOrigin, GCFont, GCSubwindowMode, GCGraphicsExposures, GCClipXOrigin, GCCLipYOrigin, GCDashOffset, GCArcMode) を含んでおり、エラーも起きなかった場合には、 XGetGCValues は引き数 values_return に要求されたコンポーネントを設定し、0 でない ステータスを返す。 そうでない場合、この関数はステータスとして 0 を返す。 clip-mask と dash-list(valuemask ではそれぞれ GCClipMaskGCDashList ビット)を要求することはできない点に注意せよ。 また、クライアントがコンポーネントを明示的に設定しなかった場合には、 GCFont, GCTile, GCStipple に対して不正なリソースIDが返される(3つの最上位ビットのうちの1つ以上が1 に設定される)点にも注意すること。

関数 XFreeGC は指定した GC を破棄し、対応するメモリを解放する。

XFreeGC はエラー BadGC を起こすことがある。

構造体

XGCValues 構造体の内容を示す。

#define GCFunction (1L<<0)
#define GCPlaneMask (1L<<1)
#define GCForeground (1L<<2)
#define GCBackground (1L<<3)
#define GCLineWidth (1L<<4)
#define GCLineStyle (1L<<5)
#define GCCapStyle (1L<<6)
#define GCJoinStyle (1L<<7)
#define GCFillStyle (1L<<8)
#define GCFillRule (1L<<9)
#define GCTile (1L<<10)
#define GCStipple (1L<<11)
#define GCTileStipXOrigin (1L<<12)
#define GCTileStipYOrigin (1L<<13)
#define GCFont (1L<<14)
#define GCSubwindowMode (1L<<15)
#define GCGraphicsExposures (1L<<16)
#define GCClipXOrigin (1L<<17)
#define GCClipYOrigin (1L<<18)
#define GCClipMask (1L<<19)
#define GCDashOffset (1L<<20)
#define GCDashList (1L<<21)
#define GCArcMode (1L<<22)
typedef struct {
     int function;            
     unsigned long plane_mask;
     unsigned long foreground;
     unsigned long background;
     int line_width;          
     int line_style;          
     int cap_style;           
     int join_style;          
     int fill_style;          
     int fill_rule;           
     int arc_mode;            
     Pixmap tile;             
     Pixmap stipple;          
     int ts_x_origin;         
     int ts_y_origin;
     Font font;               
     int subwindow_mode;      
     Bool graphics_exposures; 
     int clip_x_origin;       
     int clip_y_origin;
     Pixmap clip_mask;        
     int dash_offset;         
     char dashes;
} XGCValues;

GC の function 属性はドロウアブル(操作対象)の一部を他のドロウアブル (操作元)のビットを使って更新するときに用いられる。 GC の function コンポーネントは、新しい操作対象のビットが、操作元の ビットと古い操作対象のビットからどのように算出されるかを定義する。 GXcopy はカラーディスプレイで動作するので一般的には最も便利であるが、特別な アプリケーションでは他の関数を使うこともある。 特に、カラーディスプレイの特定のプレーンを使うアプリケーションではそう である。 16 の GC 操作関数が <X11/X.h> で定義されている。


関数 名前 値 操作

GXclear 0x0 0
GXand 0x1 src AND dst
GXandReverse 0x2 src AND NOT dst
GXcopy 0x3 src
GXandInverted 0x4 (NOT src) AND dst
GXnoop 0x5 dst
GXxor 0x6 src XOR dst
GXor 0x7 src OR dst
GXnor 0x8 (NOT src) AND (NOT dst)
GXequiv 0x9 (NOT src) XOR dst
GXinvert 0xa NOT dst
GXorReverse 0xb src OR (NOT dst)
GXcopyInverted 0xc NOT src
GXorInverted 0xd (NOT src) OR dst
GXnand 0xe (NOT src) OR (NOT dst)
GXset 0xf 1

グラフィックス操作の多くは、GC のピクセル値やプレーンに依存する。 プレーン属性は long 型で、プレーンごとに1ビットが割り当てられており、 描画対象のどのプレーンが変更されるか指定する。 モノクロのディスプレイは1つのプレーンしか持たず、プレーンマスクの 最下位ビットしか意味を持たない。 ディスプレイのハードウェアのプレーンが増えるに従って、プレーンマスクの より上位のビットが使われる。

グラフィックス操作では操作元と操作対象のピクセルが与えられると、 ピクセルの対応する各ビットがビットごとに演算されて、結果が得られる。 つまり、各プレーンにおいてブーリアン操作が実行される。 plane_mask は操作をプレーンの一部分に制限する。 マクロ定数 AllPlanes を使うことで、スクリーンの全てのプレーンを同時に参照することができる。 結果は以下のように計算される。

((src FUNC dst) AND plane-mask) OR (dst AND (NOT plane-mask))

foreground, background, plane_mask の値に対しては、範囲のチェックは行 われない。 これらの値は単に適切なビット数に切り詰められる。 line-width の単位はピクセル数で、1以上(wide line)か特殊な意味を持つ値 0(thin line)のどちらかである。

wide line はグラフィックスリクエストが示す軌跡の中心に描画される。 join-style か cap-style で別途に指定されなければ、端点が [x1, y1], [x2, y2] であり幅 w を持つ wide line のバウンディングボックスは以下の 実座標を持つ長方形となる。

[x1-(w*sn/2), y1+(w*cs/2)], [x1+(w*sn/2), y1-(w*cs/2)],
[x2-(w*sn/2), y2+(w*cs/2)], [x2+(w*sn/2), y2-(w*cs/2)]

ここで sn は線の角度のサインであり、cs は線の角度のコサインである。 ピクセルは線の一部であり、従ってピクセルの中心が完全にバウンディングボッ クス(これは無限に細い辺を持つと考える)の内部にあれば、このピクセルは描 画される。 ピクセルの中心がちょうどバウンディングボックスの辺の上にある場合は、バ ウンディングボックスの内部がピクセル中心のすぐ右(x の増加方向)にある時 に限り、ピクセルが線の一部となる。 ピクセルの中心が水平な辺上にある場合は特別で、バウンディングボックス内 部か境界が中心のすぐ下(y の増加方向)にあり、バウンディングボックス内部 か境界が中心のすぐ右(x の増加方向)にある時に限り、ピクセルが線の一部と なる。

line line(line-width が 0)は1ピクセル幅の線である。描画アルゴリズム は定義されておらず、デバイスに依存する。 このアルゴリズムに対しては2つの制約しかない。

1.
線がクリップされずに [x1,y1] から [x2,y2] へ描画され、他の線がクリップ されずに [x1+dx,y1+dy] から [x2+dx,y2+dy] へ描画された場合、点 [x+dx, y+dy] が2番目の線の描画によって塗られた場合に限り、点 [x, y] が最初の 線の描画により塗られる。
2.
線を構成する有効な点は、クリッピングによる影響を受けない。 点がクリップされた線によって塗られるのは以下の二つの条件が満たされてい る場合だけとなる: (1)その点がクリッピング領域の内部にある。 (2)線がクリップされずに描かれた場合に、その点は塗られる。

cap-style や join-style を考慮に入れなければ、[x1,y1] から [x2,y2] に 描かれる wide line と [x2,y2] から [x1,y1] に描かれる wide line は常に 同じピクセルを描画する。 これは thin line でも成り立つことが望ましいが、必須ではない。 line-width が 0 の線と line-width が 1 の線の場合では、異なるピクセル が描画されてもよい。 これにより、ハードウェアで提供される線の描画機能が利用でき、正確に仕様 が決められている wide line よりずっと速く実行することができる。

一般的には、thin line の描画は幅が1の wide line よりも描画がずっと速い。 しかし、異なる描画アルゴリズムを使うため、thin line と wide line を混 在させると見栄えが良くないことがある。 ディスプレイ全体で正確かつ均一な結果が求められる場合には、クライアント は line-width を 0 ではなく 1 とすべきである。

line-style は線のどの部分が描画されるかを定義する。

LineSolid 線の全ての軌跡が描画される。
LineDoubleDash 線の全ての軌跡が描画されるが、偶数番目のダッシュ(短い線分)と奇数番目の ダッシュでは異なる色で塗られる。また、偶数番目と奇数番目のダッシュの継 ぎ目は CapButt スタイルで描画される。
LineOnOffDash 偶数番目のダッシュだけが描画され、線の内部での各ダッシュの端点では cap-style が適用される。スタイルは CapNotLast を除いて、 CapButt として扱われる。

cap-style は軌跡の端点がどのように描画されるか定義する。

CapNotLast これは CapButt とほぼ同じであるが、line-width が 0 の場合には最後の端点が描画されな い点が異なる。
CapButt 線は端点の部分で、端点を越えない四角形(線の勾配に垂直)になる。
CapRound 線の端点は、直径が line-width に等しくて端点が中心である半円となる。 (line-width が 0 ならば CapButt と等価である。)
CapProjecting 線は端で四角形になるが、軌跡は端点を越えても line-width の半分の長さ分続く。 (line-width が 0 ならば CapButt と等価である。)

join-style は wide line の角がどのように描画されるのかを定義する。

JoinMiter 2つの線の外側の辺が角で交わるまで伸ばす。 しかし、交わる角度が11度以下ならば、join-style JoinBevel が代わりに使われる。
JoinRound 角は直径が line-width であり、中心が交点である扇形となる。
JoinBevel 角における線分の端点のスタイルは CapButt であり、さらに、三角形をなす切り目の部分を塗りつぶしたものである。

端点が一致する線(x1=x2, y1=y2)に対して、cap-style が両端で指定され ると、この意味は line-width と cap-style によって決まる。

CapNotLast thin 結果はデバイス依存であるが、望ましい結果は何も描かれないことである。
CapButt thin 結果はデバイス依存であるが、望ましい結果はピクセルが1つだけ描かれることで ある。
CapRound thin 結果は CapButt/thin の場合と同じである。
CapProjecting thin 結果は CapButt/thin の場合と同じである。
CapButt wide 何も描かれない。
CapRound wide 閉じた形は端点が中心で、直径が line-width に等しい円である。
CapProjecting wide 閉じた形は座標軸に平行で、端点が中心で、辺の長さが line-width となる正 方形である。

端点が一致する線(x1=x2, y1=y2)について、join-style が片方あるいは両方 の端点に適用された場合、線が軌跡全体から取り除かれたような効果が得られ る。 しかし、全体の軌跡が自分自身と接続した単独の点から構成される、あるいは そのような点に縮小されている場合、cap-style を両方の端点に適用したよう な効果が得られる。

tile/stippleコンポーネントは無限に広い2次元平面であり、その面上で タイル/スティプルが繰り返される。 その平面がグラフィックス操作のためにドロウアブルに重ねられる場合、 タイル/スティプルの何らかのインスタンスの左上隅は、タイル/スティプル の原点座標によって指定されたドロウアブル内の座標に配置される。 タイル/スティプルとクリップの原点は、グラフィックスリクエストで指定さ れた任意の描画対象ドロウアブルの原点に対する相対座標として扱われる。 ピックスマップ tile は GC と同じルートウィンドウと同じ深さを持っていな ければならない。そうでなければ、エラー BadMatch となる。 ピックスマップ stipple は深さが1で GC と同じルートウィンドウを持たなけ ればならない。そうでなければ、エラー BadMatch となる。 fill-style が FillStippled であるが FillOpaqueStippled でないスティプル操作に対しては、スティプルパターンは1つの平面を埋める のに使われ、clip-mask と AND 演算される追加クリップマスクとして用いら れる。 サイズによっては他のサイズのものよりも処理が速いが、任意のサイズの ピックスマップをタイルやスティプルとして使うことができる。

fill-style は線描画、テキスト描画、塗りつぶしのリクエストの操作元の内容を 定義する。 全てのテキスト描画と塗りつぶしのリクエスト (例えば、 XDrawText, XDrawText16, XFillRectangle, XFillPolygon, XFillArc )と、 全ての line-style 指定付きの線描画のリクエスト (例えば XDrawLine, XDrawSegments, XDrawRectangle, XDrawArc) と、さらに line-style ( LineOnOffDash, LineDoubleDash )を指定する線描画リクエストの偶数番目のダッシュに対して、以下の項目が 適用される。

FillSolid 前景色
FillTiled タイル
FillOpaqueStippled スティプルと同じ幅と高さを持つタイル。しかし、任意の場所で背景の スティプルは 0 であり、任意の場所で前景のスティプルは1である。
FillStippled スティプルでマスクされた前景

線が line-style 付きで描画されるとき、奇数番目のダッシュは以下の方法で fill-style に制御される。

FillSolid 背景色
FillTiled 偶数番目のダッシュと同じ。
FillOpaqueStippled 偶数番目のダッシュと同じ。
FillStippled スティプルにマスクされた背景色

GC へのピックスマップの格納はコピーが行われる場合もあるし、そうでない 場合もある。 このピックスマップが後でグラフィックスリクエストの描画対象となる場合に は、その変更は GC に反映されることも反映されないこともある。 グラフィックスリクエストにおいて、ピックスマップが描画対象としても、タイルあ るいはスティプルとしても使われている場合、その結果は未定義である。

性能を最適化するためには、できるだけ同じGC(コンポーネントも変更しない) で描画を行うとよい。 GC コンポーネントを変更するコストの、異なる GC を用いる場合に対する比 率は、ディスプレイのハードウェアやサーバの実装によって決まる。 GC 情報の一部はおそらくディスプレイのハードウェアにキャッシュされるだ ろう。と同時に、キャッシュできる GC の数はそれほど多くはないだろう。

dashes 値は実際には XSetDashes で設定できる、より一般的なパターンを簡略化した形になっている。 値 N を指定することは、 XSetDashes に2つの要素を持つリスト[N, N] を指定することと同じである。 この値は 0 以外の値でなくてはならない。0 である場合には、エラー BadValue となる。

clip-mask は描画対象のドロウアブルへの書き込みを制限する。 clip-mask にピックスマップが設定された場合、このピックスマップは深さ が 1 であり、GC と同じルートウィンドウを持たなければならない。そうでな い場合にはエラー BadMatch となる。 clip-mask に None が設定された場合、クリップの原点にかかわらずピクセルは必ず描画される。 clip-mask は関数 XSetClipRectanglesXSetRegion を呼び出しても設定できる。 clip-mask のビットが1に設定されているピクセルだけが描画される。 clip-mask がカバーしている領域の外側や、clip-mask のビットが0に設定 されている領域では、ピクセルは描画されない。 clip-mask は全てのグラフィックスリクエストに影響を与える。 clip-mask は描画元はクリップしない。 clip-mask の原点は、グラフィックスリクエストで指定された任意の描画対象 ドロウアブルに対する相対座標で与えられる。

subwindow-mode には ClipByChildrenIncludeInferiors を設定できる。 ClipByChildren の場合は、描画元のウィンドウも描画先のウィンドウも、表示可能な InputOutput である子ウィンドウ全てによって追加的にクリップされる。 IncludeInferiors の場合は、描画元、描画先いずれのウィンドウに対しても下位ウィンドウによ るクリップはなされない。 つまり描画元のサブウィンドウの内容が含まれ、描画先のサブウィンドウ境界 を通り抜けた描画が行われることになる。 IncludeInferiors を、ある深さを持ち、異なる深さの下位ウィンドウをマップしているようなウィ ンドウで使っても不正ではないが、その意味はコアプロトコルでは定義されて いない。

fill-rule は どのピクセルが XFillPolygon リクエストで与えられた軌跡の内側である(描画される)か定義する。この値は EvenOddRuleWindingRule のいずれかである。 EvenOddRule の場合は、ある点から無限遠への直線が軌跡と奇数回交わる場合に、その点を 図形の内側とみなす。 WindingRule の場合は、ある点から無限遠への直線を考えたとき、これが図形に属する時計 周り方向の線分に交わる回数と、反時計周り方向の線分に交わる回数とが異なっ ていれば、その点を図形の内側とみなす。 時計周り方向の図形の線分とは、点から見た場合に直線を左から右に横切る線 分のことである。 反時計周り方向の図形の線分とは、点から見た場合に直線を右から左に横切る 線分のことである。 方向付きの線分が直線と一致する場合は考えなくてもよい。この場合は、単に 線分と一致しない別の直線を選べばよいからである。

EvenOddRule, WindingRule いずれの場合も、点の大きさは無限小で、図形の軌跡は無限に細い。 あるピクセルの中心点が図形の内側にあり、中心点が境界線上にない場合、そ のピクセルは図形の内側である。 ピクセルの中心点が境界線上にある場合、多角形の内部がこの点のすぐ右(x 座標が増加する方向)にある場合に限り、そのピクセルは図形の内側である。 中心が水平な辺の上にあるピクセルは特別なケースであり、多角形の内部がこ の点のすぐ下(y座標が増加する方向)にある場合に限り、そのピクセルは図形 の内側である。

arc-mode は XFillArcs の塗りつぶしを制御する。この値は ArcPieSlice, ArcChord のいずれかに設定される。 ArcPieSlice の場合は、円弧はパイを切った形に塗りつぶされる。 ArcChord の場合には、弧と弦に囲まれる領域が塗りつぶされる。

graphics-exposure フラグは リクエスト(および拡張で定義される同様のリクエスト)に対しての GraphicsExpose イベントの生成を制御する。

返り値

BadAlloc
要求されたリソースやサーバメモリの割り当てにサーバが失敗した。
BadDrawable
引き数 Drawable の値が、定義されている Window や Pixmap を指していない。
BadFont
引き数 Font や GContext の値が、定義されている Font を指していない。
BadGC
引き数 GContext の値が、定義されている GContext を指していない。
BadMatch
InputOnly のウィンドウが Drawable として用いられた。
BadMatch
引き数や引き数の組は正しい型や範囲を持っているが、そのリクエストが要求する 他の条件に適合できなかった。
BadPixmap
引き数 Pixmap の値が、定義されている Pixmap を指していない。
BadValue
指定された数値の中にリクエストの許容範囲を超えているものがある。引き数に対 して特定の範囲が指定されていなければ、引き数の型で定義されている全ての範 囲が許される。選択肢として定義されている引き数はこのエラーを起こすことが ある。