Mobile:NEWS 2003年12月5日 00:52 AM 更新

BREW プログラミング入門(7)
さらに描画のおはなし(1/2)

前回はリソースファイルの作成方法と、リソースからビットマップを取得して画面に表示する方法を解説しました。今回はもう少し描画関係の話をしたいと思います。

 今回解説する内容は描画関係の事柄なので、関連するインタフェースは主にIGraphics、IDisplay、IBitmap、ITransformなどです。

クリッピングとは?

 画像を表示したり、図形を描画したりする時に描画範囲をマスクすることをクリッピングといいます。描画範囲をクリッピングしてから描画関連のAPIを呼び出すと、クリッピングした領域の内部しか描画が行われません。無駄な領域の描画を行いたくないときや、あらかじめ無駄な部分を描画しないように計算してから描画することが困難な場合に、威力を発揮します。

 BREWでもクリッピングをサポートしており、IGraphicsインタフェースのSetClip関数やIDisplayインタフェースのSetClipRect関数などを使用して設定できます。ここでクリッピング関連のAPIを一覧にまとめておきます。

  • IGraphics

関数名解説
SetClipクリッピング領域を設定します
GetClipクリッピング領域を取得します

  • IDisplay

関数名解説
SetClipRectクリッピング領域(矩形)を設定します
GetClipRectクリッピング領域(矩形)を取得します

クリッピングの前提事項と制約

 上記の表で、IGraphicsインタフェースのAPIとIDisplayインタフェースのAPIが、それぞれ存在することが分かってもらえると思いますが、IGraphicsに設定したクリッピング領域はIGraphicsの描画APIにのみ有効で、IDisplayに設定したクリッピング領域はIDisplayの描画APIにのみ有効です。そして、IGraphicsに設定できるクリッピング領域は矩形以外の円や楕円も設定できるのに対して、IDisplayに設定できるのは矩形のみです。このことは少々面倒くさい事態を招きます。

 BREWで文字列を描画するにはIDisplayインタフェースを使用し、図形を描画するにはIGraphicsインタフェースを使用します(IDisplayインタフェースにも若干の図形描画APIは存在しますが、IGraphicsインタフェースのAPIのほうが使いやすいと思います。詳しくはBREW APIリファレンスなどを参照してください)。

 ということは、文字列と図形両方に対してクリッピングを行いたい場合はIDisplayとIGraphics両方に対してクリッピングの設定をしてやらなければなりません。また、IDisplayの方は矩形しか扱えないため、矩形以外のクリッピング領域は文字列には適応できないことになります。


実現可能な例と不可能な例

IGraphicsインタフェースのクリッピングを使ってみる

 それでは、クリッピングの前提事項と制約を説明したところで、クリッピングとはどのような物なのか実際に実験してみましょう。

 まずは、IGraphicsインタフェースのみを使用して図形を描いてみましょう。以下のコードは、矩形領域でクリッピングしてから、四角形と円を描いています。

IGraphics*  graphics = app->g;
// クリッピング領域を矩形に設定
clip.type = CLIPPING_RECT;
clip.shape.rect.x = 20;
clip.shape.rect.y = 20;
clip.shape.rect.dx = 80;
clip.shape.rect.dy = 80;
IGRAPHICS_SetClip(graphics,&clip,0);
// 四角形を描画
rect.x = 10;
rect.y = 10;
rect.dx = 60;
rect.dy = 50;
IGRAPHICS_DrawRect(graphics,&rect);
// 円を描画
circle.cx = 80;
circle.cy = 70;
circle.r = 40;
IGRAPHICS_DrawCircle(graphics,&circle);
// クリッピング領域をリセット
IGRAPHICS_SetClip(graphics,NULL,0);
// 画面更新
IGRAPHICS_Update(graphics);

※一部省略されています。完全なコードはこちらを参照してください(クリックで別ウィンドウにソースコード表示)

 IGRAPHICS_SetClip(graphics,&clip,0);のクリッピング領域を設定している行をコメントアウトするとクリッピングされなくなります。どのようにクリッピングが働くのかは以下の図を参照してください。


クリッピングを使用したときとそうでないとき(矩形領域)

 次に、円領域でクリッピングしてから、四角形と円を描いてみます。

IGraphics*  graphics = app->g;
// クリッピング領域を円に設定
clip.type = CLIPPING_CIRCLE;
clip.shape.circle.cx = 60;
clip.shape.circle.cy = 60;
clip.shape.circle.r = 40;
IGRAPHICS_SetClip(graphics,&clip,0);
// 四角形を描画
rect.x = 10;
rect.y = 10;
rect.dx = 60;
rect.dy = 50;
IGRAPHICS_DrawRect(graphics,&rect);
// 円を描画
circle.cx = 80;
circle.cy = 70;
circle.r = 40;
IGRAPHICS_DrawCircle(graphics,&circle);
// クリッピング領域をリセット
IGRAPHICS_SetClip(graphics,NULL,0);
// 画面更新
IGRAPHICS_Update(graphics);

※一部省略されています。完全なコードはこちらを参照してください(クリックで別ウィンドウにソースコード表示)

 矩形領域でのクリッピングの時と同様にIGRAPHICS_SetClip(graphics,&clip,0);の行をコメントアウトするとクリッピングされなくなります。


クリッピングを使用したときとそうでないとき(円領域)

 IGraphics インタフェースではこのほかにも、楕円領域でのクリッピングが可能です(ほかにも、クリッピングに設定できる領域は定義されていますが、現在のBREWではサポートしていないようです)。

IDisplayインタフェースのクリッピングを使ってみる

 では次に、IDisplayインタフェースを使用して文字列と図形を描いてみましょう。以下のコードは、矩形領域でクリッピングしてから、文字列と四角形を描いています。

IDisplay*  display = app->a.m_pIDisplay;
const AECHAR  str[] = {'B','R','E','W',' ',
    'B','R','E','W',' ','B','R','E','W','\0'};
// クリッピング領域を矩形に設定
clip.x = 20;
clip.y = 20;
clip.dx = 80;
clip.dy = 80;
IDISPLAY_SetClipRect(display,&clip);
// 描画色を赤色で四角形を描画
rect.x = 10;
rect.y = 10;
rect.dx = 60;
rect.dy = 50;
IDISPLAY_DrawRect(display,&rect,
    MAKE_RGB(0xFF,0x88,0x88),MAKE_RGB(0xFF,0xCC,0xCC),
    IDF_RECT_FRAME | IDF_RECT_FILL);
// 文字列を描画
IDISPLAY_DrawText(display,AEE_FONT_NORMAL,
    str,-1,0,55,NULL,IDF_TEXT_TRANSPARENT);
IDISPLAY_DrawText(display,AEE_FONT_NORMAL,
    str,-1,20,70,NULL,IDF_TEXT_TRANSPARENT);
// クリッピング領域をリセット
IDISPLAY_SetClipRect(display,NULL);
// 画面更新
IDISPLAY_Update(display);

※一部省略されています。完全なコードはこちらを参照してください(クリックで別ウィンドウにソースコード表示)

 IDISPLAY_SetClipRect(display,&clip);のクリッピング領域を設定しているコードをコメントアウトするとクリッピングされなくなります。


クリッピングを使用したときとそうでないとき(IDisplay)

実際のアプリでのクリッピング

 ここまでは、IGraphicsとIDisplayを単独で使用したときの処理を例に示してみましたが、実際のアプリではIGraphicsとIDisplayを混在させて使用する事が多いと思います。例えば、以下のようなデザインを表示させる時には混在させて使用しなければなりません。


IGraphicsとIDisplayを混在させなければならないとき

 また、クリッピングの制約でも示しましたが、文字列を矩形以外でクリッピングすることは不可能です。同様に、IDisplayを使用するビットマップの描画時も矩形以外でクリッピングすることはできません。どうしても矩形以外でクリッピングしたいときは、ビットマップレベルで透過色で処理する方法があります。

 では、上の図に示したデザインを表示するコードを下に示します。

IGraphics*  graphics = app->g;
IShell*  shell = app->a.m_pIShell;
IDisplay*  display = app->a.m_pIDisplay;
const AECHAR  str[] = {'B','R','E','W',' ',
    'B','R','E','W',' ','B','R','E','W','\0'};
// クリッピング領域を矩形に設定
clip.type = CLIPPING_RECT;
clip.shape.rect.x = 20;
clip.shape.rect.y = 20;
clip.shape.rect.dx = 80;
clip.shape.rect.dy = 80;
IGRAPHICS_SetClip(graphics,&clip,0);
IDISPLAY_SetClipRect(display,&clip.shape.rect);
// ビットマップを描画
IDISPLAY_BitBlt(display,0,0,100,100,bmp,0,0,AEE_RO_COPY);
// 円を描画
circle.cx = 80;
circle.cy = 70;
circle.r = 40;
IGRAPHICS_DrawCircle(graphics,&circle);
// 文字列を描画
IDISPLAY_DrawText(display,AEE_FONT_NORMAL,
    str,-1,0,55,NULL,IDF_TEXT_TRANSPARENT);
IDISPLAY_DrawText(display,AEE_FONT_NORMAL,
    str,-1,20,70,NULL,IDF_TEXT_TRANSPARENT);
// クリッピング領域をリセット
IGRAPHICS_SetClip(graphics,NULL,0);
IDISPLAY_SetClipRect(display,NULL);
// 画面更新
IGRAPHICS_Update(graphics);
IDISPLAY_Update(display);

※一部省略されています。完全なコードはこちらを参照してください(クリックで別ウィンドウにソースコード表示)

[堀口淳史, ITmedia]

Copyright © ITmedia, Inc. All Rights Reserved.

前のページ | 1/2 | 次のページ



モバイルショップ

最新CPU搭載パソコンはドスパラで!!
第3世代インテルCoreプロセッサー搭載PC ドスパラはスピード出荷でお届けします!!

最新スペック搭載ゲームパソコン
高性能でゲームが快適なのは
ドスパラゲームパソコンガレリア!