グラフィック描画を行うデバイスコンテキストのマッピングモード(座標系)は、デフォルトでは描画時に指定する論理ピクセルと実際に描画される物理ピクセルが1:1で対応し、Xは右に行くほど、Yは下に行くほど増えるようになっています。つまり、(0,0)から100×100の正方形を描くとその正方形はデバイスコンテキストの(0,0)の位置から右に100ピクセル、下に100ピクセルの大きさで描かれるわけです。ここでは、100×100という「論理単位」で指定した大きさがそのまま画面上のピクセルという「物理単位」になっていますね。
しかし、WindowsではデバイスコンテキストのマッピングモードをSetMapMode()で変更する事が出来ます。SetMapMode()でマッピングモードを変更すると、例えば「100mm×100mmの正方形を描く」といった事が出来る(この場合は、デバイス上で100mmに対応するピクセル分の正方形になる)ので、特にプリンタのデバイスコンテキストを取得してドキュメントを印刷する時に役立つでしょう。
今回は、256×256論理単位の正方形を描いてみて、それがデバイスコンテキストの各マッピングモードでどのように表示されるか見てみる事にしましょう。
主なマッピングモード
今回取り上げるマッピングモードは、以下のとおりです。
マッピングモード | 1論理単位 | 座標方向 |
---|---|---|
MM_TEXT | 1物理単位(デバイスの1ピクセル) | 右下 |
MM_LOENGLISH | 0.01インチ | 右上 |
MM_HIENGLISH | 0.001インチ | 右上 |
MM_LOMETRIC | 0.1mm | 右上 |
MM_HIENGLISH | 0.01mm | 右上 |
MM_TWIPS | 1/1440インチ | 右上 |
*他にも、MM_ISOTROPICやMM_ANISOTROPICというマッピングモードもあるのですが、今回は扱いません。
各マッピングモードで100論理単位の線を描くと、MM_TEXTでは表示デバイスの100ピクセルで、MM_LOENGLISHでは1インチで、MM_HIENGLISHでは0.1インチで表示される事になります。また、座標系の方向はMM_TEXT以外は上に行くほどYが増えるのでDIB(そして、数学のグラフ)と同じですね。
ただし、座標の原点(0,0)はデフォルトでは物理座標の(0,0)、つまりクライアント領域の左上端にあるのでMM_TEXT以外で描画する場合は注意が必要です。このままでは、Yに正の値を指定するとそれは「左上端の原点の上」に描かれるので表示されません。マイナスの値を指定すれば表示されますが、それよりも座標系の「原点」を移動した方が良いでしょう。原点を移動するにはSetViewportOrgEx()に物理単位で原点を指定します。例えば、クライアント領域のデバイスコンテキストhdcに対して
SetViewportOrgEx(hdc,0,256,NULL);
とすると、原点がクライアント領域の(0,256)に設定されます。
マッピングモード設定と描画
では、各マッピングモードの表示を見てみる事にしましょう。今回は、ウインドウプロシージャのWM_PAINTでマッピングモードを変更し、原点を(0,256)にします。マッピングモードは定数で与えますが、今回のプログラムではその定数を変数dwMMで指定する事にしました。こうすれば、プログラムの方でdwMMを変更すればマッピングモードを変更できます。SetMapMode(hdc,dwMM); SetViewportOrgEx(hdc,0,256,NULL);
マッピングモードを変更したら、256ピクセル四方の正方形を描いてその中に三角形を描くようにしました。
Rectangle(hdc,0,0,255,255); MoveToEx(hdc,0,0,NULL); LineTo(hdc,128,255); LineTo(hdc,255,0);
プログラム
マッピングモードはメニューで変更できるようにしたので、実行したらマッピングモードメニューでマッピングモードを変更してみてください。メニューを選ぶとdwMMを変更してウインドウを再描画する事でマッピングモードの変更が反映されるようになっています。各マッピングモードで、正方形の大きさや位置そして正方形内の三角形の方向などを確認したら、画面の解像度を変えて正方形の大きさがどうなるか見てみましょう。