ディスプレイプリミティブで取り扱う座標系は、 16ビット整数値(- 32768 〜32767 ) で表わされる整数座標系であり、水平座標値は右方向に増加し、垂直座標値は下方向に増加する。
点 (Point) は、座標系上での位置を表わすための基本的な概念であり、 以 下の構造体により定義される(基本データタイプに関しては 「第1編 第1章 基本データタイプ」を参照の事)。
/* 点 */ typedef struct Point { H x; /* 水平座標値 */ H y; /* 垂直座標値 */ } PNT;
また、長方形 (Rectangle) は、 座標系上での領域を表わすための重要な概念であり、以下の構造体により定義される。
/* 長方形 */ typedef union Rectangle { struct { H left; /* 左の座標値 */ H top; /* 上の座標値 */ H right; /* 右の座標値 */ H bottom; /* 下の座標値 */ } c; struct { PNT lefttop; /* 左上の点 */ PNT rightbot; /* 右下の点 */ } p; } RECT;
ここで取り扱う長方形は、実際には右と下の辺を含まない領域であり、以下に示す性質を持つことに注意が必要である。 (このように右と下の辺を含まない性質を長方形の half-open property と呼ぶ。)
(left <= x) && (x < right) && (top <= y) && (y < bottom)
また、長方形の集合を表現するための長方形のリスト(RectangleList) は以下のように定義される。リストの最後の要素の next は NULL(0) となる。
/* 長方形リスト */ typedef struct RectangleList { RectangleList *next; /* 次の要素へのポインタ */ RECT comp; /* 要素としての長方形 */ } RLIST;ディスプレイプリミティブで取り扱う座標系は、次項で説明するビットマップにより実際の表示上のイメージに対応付けられる。
ビットマップは、 図形や文字等の表示イメージを大きさ、 および色を持った点8ピクセル)の集合として表わし、その点をメモリ上の1ビット、あるいは複数ビットに一対一対応させて、実際の表示イメージの保持/操作を行なうためのデータ構造である。
ビットマップ上では以下に示す図のように、1つのピクセルが整数座標系上の1つの点に対応づけられる。
ビットマップはイメージを表現するためのデータ構造であるが、実際のイメージの色、大きさ等の属性は、ビットマップ構造としては定義されず、ビットマップの対象とするデバイスの属性として定義されることになる。
ビットマップは、基本的に連続した1次元メモリ配列を、1つの長方形領域内の点(ピクセル)の2次元配列として解釈することにより定義される。このメモリ上のビットと表示上のピクセルとの対応付けは、以下のように定義される。
ビットマップは以下の構造体により定義される。
/* ビットマップ */ #define PLANES (1) /* ダミー */ typedef struct Bitmap { UW planes; /* プレーンの数 */ UH pixbits; /* (境界/有効)ピクセルビット数 */ UH rowbytes; /* プレーンの横幅のバイト数(偶数) */ RECT bounds; /* 境界長方形(座標定義) */ UB *baseaddr[PLANES]; /* 開始アドレス(planes 個の配列) */ } BMP;
planes はプレーン数を表わし、1〜28の範囲の値でなくてはいけない。また、プレーン数 × 有効ピクセルビット数(下記) は、28以下でなくてはいけない。
pixbits は、上位バイトがピクセルビットの境界ビット数を表わし、下位バイトが有効ビット数を表わす。 境界ビット数は、ビットマップメモリ上での1ピクセル当たりのビット数を示す1〜32の範囲の値であり、通常は2のべき乗の値である。有効ビット数は、境界ビット数のうち実際に有効な下位からのビット数を示す1〜28の範囲の値である。
なお、単にピクセルビット数と言った場合は、有効ビット数を示すものとし、後に述べるピクセル値は有効ビット数をもとにしている。
rowbytes は、1つのプレーンの横幅のバイト数を示し、必ず偶数バイトとなる。
bounds は、ビットマップの大きさと座標系を示す長方形で、 左上のピクセルの座標値と、右下のピクセルの座標値を指定する。これにより、ビットマップの対象とする全体の大きさを指定するとともに、 座標系の原点 (0,0) を任意の位置に設定することができる。この bounds は通常、rowbytes で示されるビットマップのメモリ領域の大きさに一致する大きさに設定される。
baseaddr は、 各プレーン毎のビットマップの開始メモリアドレスを示す、planes 個の要素からなる配列であり、baseaddr の値が、NULL の場合は、 対応するプレーンが存在しないことを表わす。
ビットマップ上の左上のピクセルを常に(0, 0)と考えた座標値を「絶対座標」と呼び、bounds により規定される座標値、即ち、bounds.p.lefttop を左上のピクセルの座標値としたものを、「相対座標」と呼ぶ。通常は「相対座標」が使用される。
ビットマップ上で、1つのピクセルに対応する複数のビットを並べて1つの数値として見た値をピクセル値と呼ぶ。 ピクセル値は以下のように定義され、 0〜(2 ** depth −1)の範囲の値をとる。
ピクセル値は、そのピクセルの色や白黒の階調を表わすが、実際の色、階調との対応は、対象とするデバイスの属性として定義される。
なお、 ディスプレイプリミティブでは depth は最大28までであり、ピクセル値として32ビットのデータを使用し、下位の depth(最大28)ビットが有効となる。
/* ピクセル値 */ typedef W PIXVAL; /* ピクセル値 */
圧縮ビットマップは、ビットマップデータを圧縮し、サイズを小さくしたもので、主にビットマップデータの保存のために使用される。
圧縮ビットマップは、以下のように定義される。
/* 圧縮ビットマップ */ typedef struct CompactedBitmap { W compac; /* イメージ圧縮方法 */ BMP bmp; /* ビットマップ */ } CBMP;
compac はイメージの圧縮方法を示すもので以下のものとなる。
/* イメージ圧縮方法 */ enum ImageCompactionMethod { NOCOMPAC = 0, /* 非圧縮 */ MHCOMPAC = 1, /* MH符号 */ MR2COMPAC = 2, /* MR符号 (K = 2) */ MR4COMPAC = 3 /* MR符号 (K = 4) */ /* = 4〜 : 予約 */ /* < 0 : インプリメントに依存した特殊圧縮方法 */ };
NOCOMPAC (非圧縮) の場合は、ビットマップの内容は通常のビットマップと全く同一となる。圧縮の場合は、ビットマップの baseaddr[] で示されるデータ部分が圧縮された形式で格納される。
先頭のヘッダ部には以下の内容が入り、ヘッダ部の後にライン毎のMH符号列データが並ぶ。
各ラインのデータは、MH符号列、FILL(任意個の0)、 EOL(000000000001) の並びであり、最後のEOLが偶数バイト境界にくるようにFILLによりパッドされる。MH符号列、FILL、EOL はすべて、 低位アドレスのMSBから高位アドレスのLSBに向かう順番となる。
MH符号の場合と同様であり、各ラインのデータがMR符号列となる。
一般的にカラーの表示方式は、以下の2つの方法に分類される。
カラー表示の方式はデバイスに固有なものであり、デバイスごとに以下のカラー表示方式の情報を持っている。(詳細は後述)
ディスプレイプリミティブでは、カラー指定の方法として、ピクセル値による直接指定と、RGB の各要素の輝度による絶対指定の 2 種類の方法が取られる。
カラー指定は以下に定義される構造体により行なわれる。
/* カラー表現 */ struct ColorDescription { UW trans:1; /* 透明 */ UW crep:3; /* カラー表現 */ UW cval:28; /* カラー値 */ }; typedef UW COLOR; /* カラー指定 */
XXXX RRRRRRRR GGGGGGGG BBBBBBBB 赤(8) 緑(8) 青(8)
実際の描画はピクセル値により行なわれるため、描画カラーとして指定したCOLOR から実際のピクセル値への変換を行なう必要があり、この変換は以下のように行なわれる。
COLOR の下位Nビットをそのままピクセル値とし、上位ビットは無視する。ここでNは、対象ビットマップの深さを意味する。
COLOR で指定したカラーに最も近いカラーのピクセル値とする。カラーマップ方式の場合はカラーマップの検索を行ない、指定した COLOR に最も近い色のエントリのインデックスをピクセル値とする。
固定カラー方式の場合は、COLOR での標準RGB表記に最も近い色のデバイス固有のRGB表記に変換した値をピクセル値とする。
ディスプレイプリミティブの実行環境を描画環境と呼ぶ。描画環境は動的に生成され、生成時に得られる描画環境IDにより識別される。実際の描画では、この描画環境IDを指定して対象とする描画環境を指定することになる。
/* 描画環境ID */ typedef W GID; /* 描画環境ID */1つの描画環境に対して以下のデータが対応づけられる。
異なる描画環境に対するディスプレイプリミティブの関数が同時に実行されても問題が起きないようにディスプレイプリミティブ内部で排他制御が自動的に行なわれる。ただし、対象ビットマップが重なっている場合には、重なっている部分の描画結果は保証されない。
逆に、同一の描画環境に対するディスプレイプリミティブの関数が同時に実行された場合の結果は保証されない。
描画環境の生成時には、描画対象とするデバイスを示す文字列で指定する。あらかじめディスプレイプリミティブに登録されているデバイスのみが指定可能である。
ディスプレイプリミティブでかならずサポートしているデバイスとして以下のものがあげらる。
描画対象デバイスには、以下のデバイス固有の情報(仕様)が定義されており、これはビットマップ上に描画したイメージの具体的な表現の定義を意味する。
typedef struct { H attr; /* デバイスの属性 */ H planes; /* プレーン数 */ H pixbits; /* ピクセルビット数(境界/有効) */ H hpixels; /* 横のピクセル数 */ H vpixels; /* 縦のピクセル数 */ H hres; /* 横の解像度 */ H vres; /* 縦の解像度 */ H color[4]; /* カラー情報 */ H resv[6]; /* 予約 */ } DEV_SPEC;
0LMX XXXX XXXX PRRR
下位バイトが階調ビット数を表わし、上位バイトがビット位置を表わす。マップ方式の場合は、ビット位置は意味を持たず0となり、マップ方式でない場合は、ピクセル値上でのLSBを0としたビット位置を示す。
例としてピクセル値が以下のように定義されている場合は、....BBBBGGGGGGRRRRRR color[0] = 0x0006 color[1] = 0x0606 color[2] = 0x0c04となる。
カラー情報を持たない汎用メモリ描画環境の場合には、ピクセル値とカラーとの対応は定義されないことになり、COLOR で指定されるカラーについては、透明/不透明は意味あるものとして処理されるが、カラー表現についてはピクセル値/絶対値指定にかかわらず、単にピクセルの深さでマスクを取った値をピクセル値として処理されることになる。
描画環境には、生成時に指定したメモリビットマップが対応付けられ、描画環境に対する描画は、そのビットマップ上に行なわれる。
VRAM 等のビットマップでは特殊な構成を持つ場合があり、その場合にはプレーン数として負の特殊な値とする。この特殊な値はインプリメントに依存し、ディスプレイプリミティブの関数はあらかじめその値の意味を知っていることを前提とする。
プレーン数が正の値の場合は、そのビットマップのデータの意味は、標準のビットマップの定義そのものであるが、一般に主メモリ上のビットマップ以外は、ビットマップ領域のメモリ内容を直接アクセス可能であることは保証されない。
汎用メモリ描画環境には、対象とするビットマップのピクセル値の実際の意味を示すためのカラー情報を描画環境の生成時に設定することができる。
カラー情報が設定されている場合は、絶対RGBによるカラー指定はカラー情報に従ってピクセル値に変換されて実際の描画が行われる。カラー情報が設定されていない場合は、絶対RGBカラーによる指定は無視され、常にピクセル値とみなされて描画される。
ビットマップ操作関数や描画パターンで使用されるビットマップの色変換を行うため、描画環境に色変換用のカラー情報を設定することができる。
/* カラー指定 */ struct ColorSpec { W attr; /* カラー属性 */ H info[4]; /* カラー情報 */ COLOR *colmap; /* カラーマップへのポインタ */ }; typedef ColorSpec CSPEC; /* カラー指定 */
colmap は、attr & 0x8 が 0以外場合に、実際のカラーマップへのポインタを示す。0の場合は、この値は意味を持たない。
実際のカラーマップは、(最大ピクセル値+1)個の要素からなる、COLOR 値の配列であり、 その配列のインデックス(0〜最大ピクセル値)がピクセル値となる。配列の要素は、COLOR の絶対RGB表現の値となる。
描画環境において、実際に対象ビットマップ上に描画が行なわれる領域は、対象ビットマップの境界長方形 (bounds)、フレーム長方形(FrameRect)、表示長方形(VisibleRect)、設定されたクリッピング領域に含まれ、かつ、 前置長方形リストに含まれない領域となる。
クリッピング領域が未定義の場合は、 対象ビットマップの境界長方形 (bounds)に含まれる領域がすべて描画対象となる。
クリッピング領域は、以下の任意領域構造体により定義され、その座標系は相対座標で指定される。
/* 任意領域 */ #define NX 1 /* ダミー */ #define NS 1 /* ダミー */ struct HorizontalRegion { UH nx; /* 水平座標の数(偶数) */ UH x[NX]; /* 水平座標の値(nx 個の要素で値の小さい順) */ }; typedef HorizontalRegion HRGN; /* 水平領域 */ struct GenericRegion { RECT r; /* 任意領域全体を囲む最小の長方形(相対座標系) */ UW ns; /* 垂直区間数 */ struct { UH y; /* 区間の開始垂直座標値 */ HRGN *hp; /* 区間の水平領域へのポインタ */ } s[NS]; }; typedef GenericRegion GRGN; /* 任意領域 */
水平領域は1つの垂直座標値(ラスター)に対応する水平座標の領域を指定するものであり、nx は、水平座標値の個数を示し、x[0] 〜 x[nx-1] は、 水平座標値を小さい順に並べたものである。水平座標値は、任意領域全体を囲む最小の長方形の r.c.left の値を0とする非負の値で示される。
水平座標値は2つ1組であり、第一の水平座標値(小さい値)から、第二の水平座標値(大きい値)−1の水平座標値までが、対象領域となる。(第一の値は含まれるが、第二の値は含まれない:half-open)。
同一の水平座標値が2つ以上含まれていた場合、偶数回のときにはその座標値は存在しないものと見なされ、奇数回のときには1つのみ存在しているものと見なす。nx が偶数でない場合は、最後の座標値は無視される。
同一の水平領域を持つ連続した垂直座標の領域を(垂直)区間と呼び、任意領域は、いくつかの(垂直)区間により定義される。ns は区間の数を示し、 ns=0の場合は、任意領域は長方形 r に等しいことを意味する。
s[N].y は区間 N の開始垂直座標値を示し、その区間の終了垂直座標位置は、s[N+1].y−1、または r.c.bottom−1(最後の区間の時)となる。
s[N]. hp は区間 N に対応する水平領域へのポインタを示す。s[N].hp=NULLの時は、その区間は空であることを意味する。
r = (0, 0, 17, 15) ns = 11 s[0].y = 0 s[0].hp = &(2, 5, 12) s[1].y = 1 s[1].hp = &(4, 3, 8, 9, 14) s[2].y = 2 s[2].hp = &(4, 1, 7, 10, 16) s[3].y = 3 s[3].hp = &(4, 0, 6, 11, 17) s[4].y = 4 s[4].hp = &(4, 0, 5, 12, 17) s[5].y = 5 s[5].hp = &(4, 0, 4, 13, 17) s[6].y = 10 s[6].hp = &(4, 0, 5, 12, 17) s[7].y = 11 s[7].hp = &(4, 0, 6, 11, 17) s[8].y = 12 s[8].hp = &(4, 1, 7, 10, 16) s[9].y = 13 s[9].hp = &(4, 3, 8, 9, 14) s[10].y = 14 s[10].hp = &(2, 5, 12)
r = (x0, y0, x3, y3) ns = 3 s[0].y = y0 s[0].hp = &(2, x0, x2) s[1].y = y1 s[1].hp = NULL s[2].y = y2 s[2].hp = &(2, x1, x3)
r = (x0, y0, x4, y4) ns = 4 s[0].y = y0 s[0].hp = &(2, x0, x3) s[1].y = y1 s[1].hp = &(2, x0, x4) s[2].y = y2 s[2].hp = &(2, x1, x4) s[3].y = y3 s[3].hp = &(2, x1, x2)
実際の描画は、図形描画/文字描画時に指定した描画モードに従って行なわれる。
描画モードは、以下の形式の32ビットデータで指定される。
0000 0000 0000 0000 0000 PPCF MMMM MMMM M: 描画演算モード指定 F: ビットマップ形式変換指定 C: カラー変換指定 P: マスクピクセル指定
描画演算モードは、描画の対象とするピクセルに、書き込むべきピクセル値(src)と 既に現在のピクセル値(dest)と、描画後のピクセル値(result)との関係を規定するものであり、以下に示すものが用意されている。
/* 描画演算モード */ enum DrawingCopyMode { /* ピクセル値のビット単位の論理演算 */ G_STORE = 0, /* (src) --> (result) */ G_XOR = 1, /* (src) XOR (dest) --> (result) */ G_OR = 2, /* (src) OR (dest) --> (result) */ G_AND = 3, /* (src) AND (dest) --> (result) */ G_CPYN = 4, /* NOT (src) --> (result) */ G_XORN = 5, /* NOT (src) XOR (dest) --> (result) */ G_ORN = 6, /* NOT (src) OR (dest) --> (result) */ G_ANDN = 7, /* NOT (src) AND (dest) --> (result) */ G_NOP = 8 /* (dest) --> (result) */ };
ビットマップ形式変換指定は、ソースとディスティネーションのビットマップの形式(プレーン数 、 ピクセルビット数)が異なる場合は以下に示す変換を行なうことを指定する。
/* ビットマップ形式変換 */ enum BitMapFormConversion { G_CVFORM = 0x0100 /* ビットマップ形式変換 */ };
/* カラー変換 */ enum ColorConversion { G_CVCOLOR = 0x0200 /* カラー変換 */ };
マスクピクセル指定は、描画環境に定義されたマスクピクセル値の効果を指定する。
/* マスクピクセル指定 */ enum MackPixelMode { G_MASK = 0x0400 /* マスクピクセル値と同一の値の dest ピクセルのみ描画 */ G_MASKN = 0x0800 /* マスクピクセル値と異なる値の dest ピクセルのみ描画 */ }; /* 描画モード */ typedef W DCM; /* 描画モード */
描画パターンは、描画の対象となるピクセルに書き込むピクセル値を指定するために使用されるデータであり、任意の大きさの長方形のデータとして定義される。
描画対象のビットマップの境界長方形(bounds)の原点(0,0) に描画パターンデータの左上の点を揃えて、規則正しくタイルを詰めるように境界長方形の全域に置いた場合、描画の対象となるピクセルの位置のピクセル値が書き込むべきピクセル値となる。
描画パターンは、以下の3種類の方法により指定することができる。
マスクデータ、 前景色、背景色 により描画パターンを指定する。前景色、および背景色はそれぞれ透明とすることが可能であり、透明を含めた2色までの混合パターンが指定できる。
ビットマップデータにより描画パターンを指定する。指定したビットマップ上の左上隅の正方形をパターンとして指定するため、任意の色の混合パターンが可能となる。また、別にマスクデータが指定可能であり、これによりパターンの一部を透明とする事ができる。
上記1または2の方法で定義したパターンをより高速に描画するために内部形式に変換したものを指定する。この場合は、あらかじめ対象とする描画環境に対して、使用する描画パターン(上記1,2)を、指定したメモリ領域(通常はプロセスのローカルメモリ領域)上に内部パターンイメージとして生成しておく必要がある。
内部パターンイメージの形式とサイズは、描画環境、パターンタイプ、パターンのサイズ、およびインプリメントに依存する。内部パターンイメージへの変換関数、および内部パターンイメージの大きさを得るための関数が用意されている。
描画パターンは以下に示すデータにより描画時に指定することになる。
/* 描画パターン */ typedef W PatKind; /* パターンタイプ */ union pattern { struct { PatKind kind; /* パターンタイプ(=0) */ UH hsize; /* パターンの横サイズ(ピクセル数) */ UH vsize; /* パターンの縦サイズ(ピクセル数) */ COLOR fgcol; /* 前景色 */ COLOR bgcol; /* 背景色 */ UB *mask; /* パターンマスクデータへのポインタ */ } spat; struct { PatKind kind; /* パターンタイプ(=1) */ UH hsize; /* パターンの横サイズ(ピクセル数) */ UH vsize; /* パターンの縦サイズ(ピクセル数) */ UB *mask; /* パターンマスクデータへのポインタ */ BMP *bmap; /* ビットマップへのポインタ */ } mpat; struct { PatKind kind; /* パターンタイプ(=2) */ UH hsize; /* パターンの横サイズ(ピクセル数) */ UH vsize; /* パターンの縦サイズ(ピクセル数) */ UB *pat; /* 内部パターンイメージへのポインタ */ } ipat; } typedef Pattern PAT /* 描画パターン */
なお、以下のパターンマスクデータが組込みで用意されているため mask として使用することができる。(これらは、パターンのサイズに無関係に使用できる。)
/* 標準パターンマスクポインタ */ enum StdPatternMask { _FILL0 = (1), /* 0 % 塗り潰し */ _FILL12 = (2), /* 12.5% 塗り潰し */ _FILL25 = (3), /* 25 % 塗り潰し */ _FILL50 = (4), /* 50 % 塗り潰し */ _FILL75 = (5), /* 75 % 塗り潰し */ _FILL87 = (6), /* 87.5% 塗り潰し */ _FILL100 = (7) /* 100 % 塗り潰し */ }; #define FILL0 ((B*)_FILL0) #define FILL12 ((B*)_FILL12) #define FILL25 ((B*)_FILL25) #define FILL50 ((B*)_FILL50) #define FILL75 ((B*)_FILL75) #define FILL87 ((B*)_FILL87) #define FILL100 ((B*)_FILL100)
/* 標準パターンポインタ */ enum StdPattern { /* すべて、前景色:黒、背景色:白 */ _WHITE0 = (1), /* 0 % 塗り潰し */ _BLACK12 = (2), /* 12.5% 黒塗り潰し */ _BLACK25 = (3), /* 25 % 黒塗り潰し */ _BLACK50 = (4), /* 50 % 黒塗り潰し */ _BLACK75 = (5), /* 75 % 黒塗り潰し */ _BLACK87 = (6), /* 87.5% 黒塗り潰し */ _BLACK100 = (7) /* 100 % 黒塗り潰し */ }; #define WHITE0 ((PAT*)_WHITE0) #define BLACK12 ((PAT*)_BLACK12) #define BLACK25 ((PAT*)_BLACK25) #define BLACK50 ((PAT*)_BLACK50) #define BLACK75 ((PAT*)_BLACK75) #define BLACK87 ((PAT*)_BLACK87) #define BLACK100 ((PAT*)_BLACK100)
直線、弧や閉じた図形の枠の描画の場合は、描画する線の属性を以下の形で指定することができる。
0000 0000 0000 0000 TTTT TTTT WWWW WWWW W: 線幅 (下位8ビット符号無し) (0〜255) 線の幅(太さ)をピクセル数で指定したもの T: 線種 (上位8ビット符号無し) (0〜5,255) 以下に示す線種を表わす番号 /* 線種 */ enum LineKind { LN_SOLID = 0, /* 実線 */ LN_DASH = 1, /* 破線 */ LN_DOT = 2, /* 点線 */ LN_DDASH = 3, /* 一点鎖線 */ LN_DDDASH = 4, /* 二点鎖線 */ LN_LDASH = 5, /* 長破線 */ /* 予約 6〜254 (指定した場合は、EG_NOSPT のエラー) */ LN_MASK = 255 /* 指定マスク */ }; /* 線属性 */ typedef W LATTR; /* 線属性 */
描画環境には、線マスクパターンを登録しておくことが可能であり、T = 255の場合は、登録しておいた線マスクパターンを使用した線種が適用される。この線マスクパターンはデフォールトでは実線となっている。
線マスクパターンは、線幅1の時に描画対象となるピクセルを"1"のビットで示した周期的なマスクパターンとして定義され、周期の単位として8〜64ピクセルまで、8ピクセル単位で指定することができる。即ち、1〜8バイトまでバイト配列により定義される。
なお、太い線幅で描画した場合は、定義したパターンは自然な形で拡大されて描画されることになる。
文字描画は指定した文字に対応する文字イメージデータを描画することにより行なわれる。文字イメージデータは、文字(前景)部分と背景部分からなる単一プレーンのビットマップであり、文字部分と背景部分をそれぞれ何色で描画するかの以下の2種類の文字描画カラーの指定が必要になる。
実際の文字描画は文字描画カラーに従って以下に示す方法で行なわれる。
chfgc≧0: 文字前景色をピクセル値として各プレーンに対して、文字描画演算指定に従って描画する。
chfgc<0: 描画を行なわない(透明)
chbgc≧0: 文字背景色をピクセル値として各プレーンに対して、文字描画演算指定に従って描画する。
chbgc<0: 描画を行なわない(透明)
描画環境を生成した時点のデフォールトの文字描画カラーは、文字背景色は白(カラー情報を持たない場合は0)、文字前景色は黒(カラー情報を持たない場合は最大ピクセル値)となる。
描画環境には、文字描画の際に使用される、文字描画位置、文字描画方向、文字間隔 のデータが保持されている。
文字描画位置は、次に描画する文字の座標位置であり、文字(列)を描画した後は、自動的に次の描画位置に更新される。
文字描画方向は、文字の描画方向を指定するものであり、以下の値で表される。文字描画方向により、文字イメージ矩形(文字枠)のどの位置を文字描画位置とするかが一意的に決定される。
/* 文字描画方向 */ enum CharacterDirection { TORIGHT = 0; /* 右向き(文字枠のベースラインの左端が描画位置) */ TOLEFT = 1; /* 左向き(文字枠のベースラインの右端が描画位置) */ TOUP = 2; /* 上向き(文字枠の左上の点が描画位置) */ TODOWN = 3; /* 下向き(文字枠の左下の点が描画位置) */ TOARB = 4; /* 任意の向き(文字枠の左上の点が描画位置) */ };
文字間隔は、文字と文字の間隔を指定するものであり、以下の構造体データにより指定される。
/* 文字間隔 */ struct SignedGap { H dir; /* 方向 */ UH gap; /* 文字間隔 */ } typedef SignedGap SGAP; /* 文字間隔 */ struct CharacterGap { SGAP hgap; /* 水平文字間隔 */ SGAP vgap; /* 垂直文字間隔 */ SGAP hspgap; /* 空白水平間隔 */ SGAP vspgap; /* 空白垂直間隔 */ }; typedef CharacterGap CGAP; /* 文字間隔 */
水平/垂直文字間隔は、文字描画方向が TOARB 以外の場合は、 文字枠の端と次の文字枠の端との間隔を示すが、TOARB の場合は、文字描画位置と次の文字描画位置の間隔を示す。
空白水平/垂直間隔は、 空白文字(可変幅空白、コード=0x20) の直後に追加される文字間隔を示し、空白文字(可変幅空白)の幅、または高さを変更することに相当する。
文字間隔指定、SGAP の要素は以下の意味を持つ。
絶対ピクセル数指定: 1NNN NNNN NNNN NNNN 文字間隔はNピクセル数 文字サイズ比例指定: 0AAA AAAA BBBB BBBB
文字間隔は、 文字幅(水平方向の時) または文字高さ(垂直方向の時)×A/Bのピクセル数。(B=0の時は比率1とみなす)文字幅、文字高さが固定長さでない場合は、最大幅、最大高さを基準とする。
文字間隔の指定により、文字枠と次の文字枠の間に隙間ができる場合、その隙間には何も描画されないため、注意が必要である。
文字描画位置は文字を描画した後、以下に示すように更新される。
描画環境を生成した時点では、以下のデフォールト値が設定される。
文字描画で使用する文字フォントは、以下のフォント指定データにより指定される。このフォント指定により、フォントの種類、字の太さ等の属性、および文字サイズ/変形の指定を同時に行なう。指定できる文字サイズの最大はインプリメントに依存する。
/* フォント指定 */ typedef struct ExtendFontSpecifier { TC name[L_FONTFAMNM]; /* フォントファミリ名 */ UW fclass; /* フォントクラス */ UW attr; /* フォント属性 */ SIZE size; /* 文字サイズ */ } FSSPEC;
また、指定したフォントに関する以下の情報を得ることができる。
/* フォント情報 */ struct FontInfo { UH height; /* 最大文字高 (文字サイズ) */ UH width; /* 最大文字幅 */ UH base; /* ベース位置 */ UH leading; /* レディング */ }; typedef FontInfo FNTINFO; /* フォント情報 */
文字の太さ、幅、斜体(イタリック)、袋文字 等に関しては、フォント属性として指定することにより描画することが可能であるが、下線、上線、網掛け、反転、上付き、下付き、ルビ 等の処理はディスプレイプリミティブとしてはサポートしてしないため、アプリケーション側で行なう必要がある。
なお、 フォントに関する詳細は「第3章 3.9 フォントマネージャ」を参照のこと。
/* 文字コード */ typedef UH TC /* 文字コード(1文字) */