Windowsコード集 上のページ

#0005 クリップクラス

グラフィック転送時に必要になるであろう処理に、クリップ処理と言うのがあります。これは画面から画像がはみ出したりする場合においても、ただしくグラフィックが転送できるようにする物です。
GDIのみに徹する場合には内部でやってくれる物なのですが、直接操作するときやDirectDrawを使用する際にはきっと重宝するでしょう。
class CClipRect{
public:
    RECT m_dst,m_src;
    BOOL m_ok;
public:
    CClipRect(){;}
    CClipRect(RECT *dst,RECT *src,LONG dx,LONG dy,LONG sx,LONG sy,LONG nx,LONG ny){
        Clip(src,dst,dx,dy,sx,sy,nx,ny);}
    CClipRect(RECT *dst,LONG dx,LONG dy,LONG nx,LONG ny){
        Clip(dst,dx,dy,nx,ny);}
    BOOL IsOk(){return m_ok;}
    LPRECT GetDstRect(){return &m_dst;}
    LPRECT GetSrcRect(){return &m_src;}
    BOOL Clip(RECT *dst,RECT *src,LONG dx,LONG dy,LONG sx,LONG sy,LONG nx,LONG ny){
        LONG re;
        if((re = dst->left  - dx         ) > 0){dx = dst->left;nx -= re;sx += re;}
        if((re = dst->top   - dy         ) > 0){dy = dst->top ;ny -= re;sy += re;}
        if((re = dx + nx    - dst->right ) > 0){nx -= re;}
        if((re = dy + ny    - dst->bottom) > 0){ny -= re;}
        if((re = src->left  - sx         ) > 0){sx = src->left;nx -= re;}
        if((re = src->top   - sy         ) > 0){sy = src->top ;ny -= re;}
        if((re = sx + nx    - src->right ) > 0){nx -= re;}
        if((re = sy + ny    - src->bottom) > 0){ny -= re;}
        if(nx <= 0 || ny <= 0)return (m_ok = FALSE);
        m_dst.right  = (m_dst.left = dx) + nx;
        m_dst.bottom = (m_dst.top  = dy) + ny;
        m_src.right  = (m_src.left = sx) + nx;
        m_src.bottom = (m_src.top  = sy) + ny;
        return (m_ok = TRUE);
    }
    BOOL Clip(RECT *rect,LONG dx,LONG dy,LONG nx,LONG ny){
        LONG re;
        if((re = rect->left  - dx          ) > 0){dx = rect->left;nx -= re;}
        if((re = rect->top   - dy          ) > 0){dy = rect->top ;ny -= re;}
        if((re = dx + nx     - rect->right ) > 0){nx -= re;}
        if((re = dy + ny     - rect->bottom) > 0){ny -= re;}
        if(nx <= 0 || ny <= 0)return (m_ok = FALSE);
        m_dst.right  = (m_dst.left = dx) + nx;
        m_dst.bottom = (m_dst.top  = dy) + ny;
        return (m_ok = TRUE);
    }
};


// 以下はクラスの使用例です。
// まず、転送元、転送先の画像範囲を以下のように指定します。

RECT srcrect;   // 転送元
RECT dstrect;   // 転送先

srcrect.left   = 0;     // 128x128の範囲を指定します
srcrect.right  = 128;
srcrect.top    = 0;
srcrect.bottom = 128;

dstrect.left   = 0;     // 640x480の範囲を指定します
dstrect.right  = 640;
dstrect.top    = 0;
dstrect.bottom = 480;

// 以下は実際のクリップ処理です。

CClipRect clip;

// [0,0]-[100,100]の範囲にあるグラフィックを、[20,20]に転送するときのクリップ処理
if(clip.Clip(&dstrect,&srcrect,20,20,0,0,100,100)){
    // 描画が必要なとき

    // clip.GetDstRect()に転送先RECT、clip.GetSrcRect()に転送元RECTが取得できます。
}else{
    // 描画が不要なとき
    // 画面外に描画するようなときは、ここが処理されます。
}




上のページ