ビジュアルの線形性属性に応じて、表示されるカラーの彩度応答は異なります。ブラウン管 (CRT) モニターでは、表示されるカラーは実際に要求されたカラーよりも暗くなります。このような暗化現象の原因は、モニターの物理的構造にあります。デバイスによってはこの暗化現象を補正するビジュアルをサポートしています。これを「ガンマ補正」と呼びます。
ガンマ補正は、フレームバッファから出る色を変更し、モニターの応答を反転させることによって行われます。ガンマ補正ビジュアル全体の彩度は直線的に変化するので、ガンマ補正ビジュアルのことを線形ビジュアルといいます。ガンマ補正されていないビジュアルを非線形ビジュアルといいます。
線形性は、X11 ビジュアルの標準属性ではありません。しかし、一部のアプリケーションでは、視覚的な悪影響を避けるために線形ビジュアルが必要になります。たとえば、平滑化された線分を使用するグラフィックスアプリケーションでは、線形ビジュアルを使用しなければ、好ましくない「ローピング」アーティファクトが生じることがあります。このようなアプリケーションは線形アプリケーションと呼ばれます。カラーの最適な表示に非線形ビジュアルを必要とするアプリケーションは、非線形アプリケーションと呼ばれます。ほとんどの X11 アプリケーションは、非線形アプリケーションです。
ほとんどのデバイス上のデフォルトビジュアルは非線形です。したがって、線形アプリケーションはデフォルトビジュアルを使用せず、線形ビジュアルを常に明示的に探索しなければなりません。同様に、非線形アプリケーションの場合も、非線形ビジュアルを明示的に検索するとよいでしょう。これは一般にほとんどのデバイスのデフォルトなので不可欠ではありませんが、望ましい方針ということができます。
ビジュアルが線形かどうかを判断するには、アプリケーションはインタフェース XSolarisGetVisualGamma(3) を使用できます。ガンマ補正についての詳細は、Foley and Van Dam 著『Fundamentals of Computer Graphics』を参照してください。
Solaris 環境では XSolarisGetVisualGamma(3) を呼び出してビジュアルのガンマ値を調べれば、線形性を確定することができます。ガンマ値が 1.0 に等しければ (あるいは 1.0 に近ければ) 、ビジュアルは線形です。それ以外の場合、ビジュアルは非線形です。経験上の法則として誤差の許容範囲は 10% 以内です。XSolarisGetVisualGamma API を使用するには、アプリケーションを Solaris の libXmu とリンクしなければなりません。
例 3-1 は、代表的な XGLTM 3D 線形アプリケーションに最適なビジュアルを選択する例です。この例では、線形ビジュアルが見つからない場合は非線形ビジュアルを使用しています。この例は単に、ビジュアルを選択する 1 つの方法を示すものです。
デバイス上のビジュアルのガンマが再構成または測定によって変更された場合は、ウィンドウシステムを再起動する必要があります。そうしないと、すでにXSolarisGetVisualGamma を使用して動作しているアプリケーションは変更されたビジュアルを検出できず、誤ったビジュアルを参照してしまう場合があります。
/* ** 指定されたデプス、クラス、線形性を持つビジュアルを戻す ** 見つからない場合は NULL を戻す */ Visual * match_visual (Display *dpy, int screen, int depth, int class, Bool wantLinear) { XVisualInfo template; XVisualInfo *vinfo, *vi; int nitems, isLinear, i; double gamma; template.screen = screen; template.depth = depth; template.class = class; if (!(vinfo = XGetVisualInfo(dpy, VisualScreenMask | VisualDepthMask | VisualClassMask, &template, &nitems)) || nitems <= 0) { return (NULL); } for (i = 0, vi = vinfo; i < nitems; i++, vi++) { if (XSolarisGetVisualGamma(dpy, screen, vi->visual, &gamma) == Success) { /* ** ビジュアルの線形性に関する経験則では ** ガンマが 1.0 の 10% の範囲内にあれば線形と見なされる */ isLinear = (gamma >= 0.9 && gamma <= 1.1); if ((wantLinear && isLinear) || (!wantLinear && !isLinear)) { Visual *visual = vi->visual; XFree(vinfo); return (visual); } } } XFree(vinfo); return (NULL); }
この例の main ルーチンを以下に示します。
main () { Visual vis; ... if ((vis = match_visual(display, screen, 24, TrueColor, True))) { fprintf(stderr, "Found a linear 24-bit TrueColor visual¥n"); visualClass = TrueColor; depth = 24; } else if ((vis = match_visual(display, screen, 24, TrueColor,False))){ fprintf(stderr, "Found a nonlinear 24-bit TrueColor visual¥n"); visualClass = TrueColor; depth = 24; } else if ((vis = match_visual(display, screen, 8, PseudoColor,False))){ fprintf(stderr, "Found a nonlinear 8-bit PseudoColor visual¥n"); visualClass = PseudoColor; depth = 8; } else { fprintf(stderr, "Cannot match 24 or 8 bit visual¥n"); exit(1); } ... }
上記のコード例では、ビジュアルを選択する方法を 1 つだけ示しましたが、他の方法を採用することもできます。各種のビジュアル構成を処理できるようなアプリケーションを作成することをお勧めします。GX のような一部のデバイスでは、線形ビジュアルがサポートされません。また、単一の線形 24 ビット TrueColor ビジュアルだけをサポートするデバイスがあります。さらに、線形ビジュアルと非線形ビジュアルが同時にサポートされるデバイスもあります。一般に、移植性のあるアプリケーションを作成する最も賢明な方法は、これらすべての構成を細かく操作することです。希望の線形性を持つビジュアルが見つからない場合は、警告メッセージを出力するようにします。あるいは、線形アプリケーションで線形ビジュアルが見つからない場合は、便利なトリックとして、X11 に与えられたカラーをアプリケーション内で手作業で暗くする方法もあります。これは独自のガンマ補正を実行するのと同じことです。カラーをどの程度暗くするかは、XSolarisGetVisualGamma で戻されるガンマ値から判断できます。
XSolarisGetVisualGamma は、Solaris の「公開」インタフェースで、全面的にサポートされます。将来は、カラー管理システムでもこの機能が提供される可能性があります。そうすれば、この情報を取得する上で望ましい方法となります。しかし、それまでは XSolarisGetVisualGamma を使用してガンマ値を調べてください。このカラー管理システムが導入されると、XSolarisGetVisualGamma を使用するアプリケーションは修正しなくても引き続き動作し、実際にはカラー管理システムによって精度が高くなるという利点が得られます。