前のページ次のページ上に戻るホーム SophiaFramework UNIVERSE 5.3

12.1. 描画の方法

図形やテキストは、SFXGraphics クラスを利用して画面に描画します。 SFXGraphics クラスは SFBGraphics クラスと SFBDisplay クラスを抽象化したクラスです。

SFXGraphics クラスは、 SFBGraphics クラスの図形を描画するための関数と SFBDisplay クラスのテキストを描画するための関数を継承しているため、 図形とテキストの描画に関してクリッピングや原点の移動などが簡単に行えます。

図形やテキストを描画するための SFXGraphics インスタンスは、 アプレット起動時に自動的に生成され、アプレット終了時に自動的に解放されます。 そのため、SFXGraphics インスタンスの初期化処理や終了処理は不要です。

SFXGraphics インスタンスは、 SFXGraphics::GetInstance 関数を使用して取得します。 あるいは、描画ハンドラの引数として渡されます。

描画の対象となるターゲットビットマップは、SFXGraphics::SetDestination 関数で設定します。 デフォルトの設定では、デバイスビットマップがターゲットビットマップです。

GUI フレームワークを利用する場合は、 レスポンダ領域(ローカル領域)の左上端を原点とする相対座標系で描画を行えるように自動的に原点が移動します。

描画内容を実際に画面に反映させるには、 SFXGraphics::BitBlt 関数を呼び出してターゲットビットマップの内容をデバイスビットマップに転送し(デフォルトの設定の場合は不要)、 SFXGraphics::Update 関数を呼び出す必要があります。 GUI フレームワークを使用する場合、この処理は SFYResponder::Render 関数内で自動的に行われます(SFXGraphics::Update 関数の呼び出しは不要です)。

たとえば、矩形を画面に描画するには以下のように記述します。

// SFXGraphics インスタンスを取得する
SFXGraphicsPtr graphics = SFXGraphics::GetInstance();

// 画面の矩形 rectangle を取得する
SFXRectangle rectangle(SFXGraphics::GetDeviceRectangle());

// 矩形 rectangle を白色に塗りつぶす
graphics->ClearRectangle(rectangle, SFXRGBColor(0xFF, 0xFF, 0xFF, 0x00));

// 前景色を青色にする
graphics->SetForeColor(SFXRGBColor(0x00, 0x00, 0xFF, 0x00));
   
// 塗り潰しモードをオフにする
graphics->SetFillMode(false);

// 矩形 rectangle を上下左右 10 ピクセルずつ縮小した矩形を描画する
graphics->DrawRectangle(rectangle.Deflate(10, 10));

// 画面を更新する
graphics->Update();

図 12.1. 実行結果[矩形の描画]

実行結果[矩形の描画]

また、テキストを描画するには以下のように記述します。

// SFXGraphics インスタンスを取得する
SFXGraphicsPtr graphics = SFXGraphics::GetInstance();

// 画面の矩形 rectangle を取得する
SFXRectangle rectangle(SFXGraphics::GetDeviceRectangle());

// 矩形 rectangle を白色に塗りつぶす
graphics->ClearRectangle(rectangle, SFXRGBColor(0xFF, 0xFF, 0xFF, 0x00));

// "Hello World" を黒色で描画する
graphics->DrawSingleText("Hello World", rectangle, SFXRGBColor(0x00, 0x00, 0x00, 0x00));

// 画面を更新する
graphics->Update();

図 12.2. 実行結果[テキストの描画]

実行結果[テキストの描画]

長いテキストを自動改行して描画する関数も用意されています。 下記サンプルコードでは、この関数を使用して画面上に指定された矩形(画面全体の矩形を上下左右 5 ピクセルずつ縮小した矩形)内に文章を青色で描画しています。

// SFXGraphics インスタンスを取得する
SFXGraphicsPtr graphics = SFXGraphics::GetInstance();

// 画面の矩形 rectangle を取得する
SFXRectangle rectangle(SFXGraphics::GetDeviceRectangle());

// 矩形 rectangle を白色に塗りつぶす
graphics->ClearRectangle(rectangle, SFXRGBColor(0xFF, 0xFF, 0xFF, 0x00));

// 前景色を青色にする
graphics->SetForeColor(SFXRGBColor(0x00, 0x00, 0xFF, 0x00));
// 矩形 rectangle を上下左右 5 ピクセルずつ縮小した矩形内に文章を青色で描画する
graphics->DrawMultipleTextLeft("Ladies and Gentleman, SophiaFramework UNIVERSE is "
                                  "the most powerful GUI frameowk library in the BREW world.",
                                  rectangle.Deflate(5, 5), 
                                  SFXGrid(5, 5), 
                                  rectangle.GetWidth() - 5 * 2 );

// 画面を更新する
graphics->Update();

図 12.3. 実行結果[長いテキストの描画]

実行結果[長いテキストの描画]

原点移動を行うには以下のように記述します。

下記のサンプルコードでは、描画の原点を (-50, -50) に移動して描画を行っています。 画面左上端を原点とする座標系で表すと移動前の原点は (50, 50) に移動したことになります。

// SFXGraphics インスタンスを取得する
SFXGraphicsPtr graphics = SFXGraphics::GetInstance();

// 原点を移動する前の画面領域を矩形 rectangle に保存する
SFXRectangle rectangle(SFXGraphics::GetDeviceRectangle());

// 原点を (-50, -50) に移動する[(-50, -50)が画面左上端になる]
graphics->SetTranslate(SFXGrid(-50, -50));

// 矩形 rectangle を灰色に塗りつぶす
graphics->ClearRectangle(rectangle, SFXRGBColor(0xDD, 0xDD, 0xDD, 0x00));

// 前景色を青色にする
graphics->SetForeColor(SFXRGBColor(0x00, 0x00, 0xFF, 0x00));
   
// 塗り潰しモードをオフにする
graphics->SetFillMode(false);

// 矩形 rectangle を上下左右 30 ピクセルずつ縮小した矩形を描画する
graphics->DrawRectangle(rectangle.Deflate(30, 30));

// 画面を更新する
graphics->Update();

図 12.4. 実行結果[原点の移動]

実行結果[原点の移動]
[Caution] 注意

SFXGraphics クラスの使用方法は GUI フレームワークを使う場合と使わない場合で異なります。

12.1.1. GUI フレームワークを使うとき

描画ハンドラの引数として渡される SFXGraphics インスタンスを利用して、 レスポンダのローカル領域の相対座標系(ローカル領域の左上端が原点)で図形やテキストを描画します。

[Note] 原点移動

図形やテキストをローカル領域の相対座標系で行うための原点移動は SophiaFramework UNIVERSE 内部で自動的に行われます。

例 12.1. ウィンドウ内での描画

// MyWindow の定義
SFMTYPEDEFRESPONDER(MyWindow)
class MyWindow : public SFZWindow
{
    SFMSEALRESPONDER(MyWindow) 
    SFMRESPONDERINSTANTIATEFOUR(MyWindow, SFZWindow, SFYContainer, SFYWidget, SFYResponder)
public:
    enum CodeEnum {
        CODE_TYPE = four_char_code('M', 'W', 'N', 'D')
    };
public:
    static MyWindowSmp NewInstance(SFCErrorPtr exception = null);
protected:
    explicit MyWindow(Void) static_throws;
    virtual ~MyWindow(Void);

    // 描画ハンドラ(描画イベント発生時に最初に呼び出される HandleRenderRequest 仮想関数をオーバーライドする)
    virtual Void HandleRenderRequest(SFXGraphicsPtr graphics) const; 

private:
    // キーハンドラ
    XANDLER_DECLARE_BOOLEVENT(OnKey)
};

// 黒色
#define COLOR_BLACK                 (SFXRGBColor(0x00, 0x00, 0x00, 0x00))
// 薄緑色
#define COLOR_MY_WINDOW_BACK        (SFXRGBColor(0xCC, 0xFF, 0xCC, 0x00))

// MyWindow の描画ハンドラ
Void MyWindow::HandleRenderRequest(SFXGraphicsPtr graphics) const
{
    // 描画を行うための SFXGraphics インスタンスは第 1 引数(graphics)として渡される
    // MyWindow のローカル領域の左上が描画領域の原点となる

    // GetLocalBound 関数で MyWindow のローカル領域を取得する
    // MyWindow のローカル領域を薄緑色で描画する
    graphics->FillRectangle(GetLocalBound(), COLOR_MY_WINDOW_BACK);

    // MyWindow のローカル領域中央に "Hello Window" を黒色で描画する
    graphics->DrawSingleText("Hello Window", GetLocalBound(), COLOR_BLACK);

    // GUI フレームワークを利用するときは graphics->Update() の実行は不要

    return;
}
[Caution] SFXGraphics::Update 関数の呼び出し

GUI フレームワークを利用するときは、SFXGraphics::Update 関数を呼び出す必要はありません。 描画ハンドラ実行後に SophiaFramework UNIVERSE の描画エンジンが自動的に呼び出します。

[Note] 詳細内容

上記コードの詳細については、ウィンドウをご覧になってください。

図 12.5. 実行結果[ウィンドウ内での描画]

実行結果[ウィンドウ内での描画]
[Note] 描画のタイミング

描画ハンドラは、 イベントループの最後のタイミングで呼ばれます。

12.1.2. GUI フレームワークを使わないとき

任意の場所で SFXGraphics::GetInstance 関数を使用して SFXGraphics インスタンスを取得して 描画します。

例 12.2. 矩形とテキストの描画

Void Draw(Void)
{
    // SFXGraphics インスタンスの取得
    SFXGraphicsPtr graphics = SFXGraphics::GetInstance();

    if (graphics == null) { 

        // エラーが発生したとき
		...

        return;
    }

    // 画面を白色に塗りつぶす
    // SFXGraphics::GetDeviceRectangle() で画面全体の矩形を取得する
    // SFXRGBColor(0xFF, 0xFF, 0xFF, 0x00) = 白色
    graphics->FillRectangle(SFXGraphics::GetDeviceRectangle(),
                            SFXRGBColor(0xFF, 0xFF, 0xFF, 0x00));

    // 画面に "Hello World" を描画する
    // SFXRGBColor(0x00, 0x00, 0x00, 0x00) = 黒色
    graphics->DrawText("Hello World", SFXGraphics::GetDeviceRectangle(),
                       SFXRGBColor(0x00, 0x00, 0x00, 0x00));

    // GUI フレームワークを利用しないので画面を更新する
    graphics->Update();
}
[Caution] SFXGraphics::Update 関数の呼び出し

GUI フレームワークを利用しないときは、明示的に SFXGraphics::Update 関数を呼び出す必要があります。 この関数を呼び出さなければ、画面は更新されません。

図 12.6. 実行結果[矩形とテキストの描画]

実行結果[矩形とテキストの描画]