- 追加された行はこのように表示されます。
- 削除された行は
このように表示されます。
{{category 開発情報}}
{{category 陰郎の書いた記事,nolink}}
!!概要
このページでは、Double density 環境(いわゆるハイレゾ)において小さな ── 通常 Small / Tiny と呼ばれている ── フォントを描画する方法について説明します。
!!説明
まず、オフスクリーンウィンドウに文字を描画する方法からおさらいします。前提は Double density ですから、ビットマップを作成してから文字を描画するまでの方法は以下のようになります(ここでは作成するビットマップのサイズは適当です)。
BitmapType* pBitmap;
BitmapTypeV3* pBitmapV3;
WinHandle offscreen;
RectangleType rect;
UInt16 err;
pBitmap = ::BmpCreate( 320, 30, 1, 0, &err );
pBitmapV3 = ::BmpCreateBitmapV3( pBitmap, kCoordinatesDouble,
::BmpGetBits( pBitmap ), NULL );
offscreen = ::WinCreateBitmapWindow( (BitmapType*)pBitmapV3, &err );
::WinSetDrawWindow( offscreen );
::WinDrawChars( "Palm", 4, 0, 0 );
では、ひとまずこれを実際の画面に転写してみましょう。
::RctSetRectangle( &rect, 0, 0, 320, 30 );
::WinCopyRectangle( offscreen, current, &rect, x, y, winPaint );
こうすることで、画面は以下のように描画されます(拡大して罫線を入れてあります)。
{{ref_image Sample01.gif}}
さて、ここまでは教科書どおりです。では、ついうっかり BmpCreateBitmapV3 で kCoordinatesStandard を指定してしまったらどうなるでしょう。
pBitmap = ::BmpCreate( 320, 30, 1, 0, &err );
pBitmapV3 = ::BmpCreateBitmapV3( pBitmap, kCoordinatesStandard, // Double じゃない!
::BmpGetBits( pBitmap ), NULL );
offscreen = ::WinCreateBitmapWindow( (BitmapType*)pBitmapV3, &err );
::WinSetDrawWindow( offscreen );
::WinDrawChars( "Palm", 4, 0, 0 );
この時点で、オフスクリーンのウィンドウ上では、以下のようになっているはずです。
{{ref_image Sample02.gif}}
で、これを実際の画面に転写します。方法は先程と同じです。この場合、画面には以下のように表示されます。
{{ref_image Sample03.gif}}
拡大されましたね...ここで何が起きているのかを良く考えてみましょう。オフスクリーンウィンドウは Single density であり、転写先の実際の画面は Double density です。このような状態での転写では、スケールの適切な変換が自動的に行われるようになっているわけですね。
では、これにちょっと手を加えてみます。Single density でオフスクリーンウィンドウに文字列を描画するところまでは同じですが、実際の画面に転写する前に Double density 扱いに変えてしまうのです...以下のように。
::WinSetDrawWindow( offscreen );
::WinDrawChars( "Palm", 4, 0, 0 );
// 追加ココから ─────────────────────
::WinDeleteWindow( offscreen, false );
::BmpSetDensity( (BitmapType*)pBitmapV3 , kCoordinatesDouble );
offscreen = ::WinCreateBitmapWindow( (BitmapType*)pBitmapV3, &err );
// 追加ココまで ─────────────────────
::RctSetRectangle( &rect, 0, 0, 320, 30 );
::WinCopyRectangle( offscreen, current, &rect, x, y, winPaint );
すると、実際の画面には以下のように描画されます。
{{ref_image Sample02.gif}}
...はい、小さなフォントの描画の出来上がりです。つまり、オフスクリーンへの描画を Single density で実行し、実際の画面に転写する前に Double density のウィンドウを作り直すことで実現しているんですね。WinDeleteWindow を実行してもビットマップ自体を削除するわけではないため、再度作成したオフスクリーンウィンドウにはそのままデータが残っているわけです。
これの逆をやることで「 文字を拡大 」できることに気づいた方も多いと思います。つまり、Double density でオフスクリーンウィンドウに描画し、Single density にしてから画面に転写するということですね。これについては読者の練習課題としたいと思います。
!!サンプルプログラム
このページで紹介している方法で小さなフォントを描画するサンプルプログラムを用意しました。標準的に使用される4つのフォントと、それぞれの半分のサイズの計8種類の文字列を表示します。
{{ref_image FontScaleSample.gif}}
このサンプルプログラムのソースコード一式は以下からダウンロードできます。
*{{ref FontScale.zip}}
このサンプルプログラムは CodeWarrior 9.0J で開発、動作確認を行っています。サンプルを作成する時間的余裕があまりなかったため、C++ & POL を使用しています。C++ についてよくわからなければ、MainForm.cpp の DrawChars 関数だけを見るのが良いでしょう。また、あくまでサンプルであるため、実装は決して処理効率の良いものではないことを注記しておきます。あと、クリエータIDは 'STRT' のままになっていますのでご注意ください。
!!参考情報
このページで紹介しているテクニックは、山田達司さんが公開されている J-Doc Reader 4.0b3 のソースコードで使用されている方法です。このテクニックの記事としての掲載に御快諾くださった山田達司さんに感謝いたします。
J-Doc Reader は他にもいろいろなテクニックが使用されているアプリケーションです。興味のある方は是非公開されているソースコードを参照してみてください。
!!コメント
*コメントスパムが来ますので、コメント欄をコメントアウトしました。コメントを追加したい方は、コメント欄の復活させるか、または直接編集してください。- よういち (2007年02月07日 09時05分00秒)
//{{comment multi}}