cardrgndraw.cpp

来自「一个类似windows」· C++ 代码 · 共 614 行 · 第 1/2 页

CPP
614
字号
//
//    CardLib - CardRegion drawing support
//
//    Freeware
//    Copyright J Brown 2001
//
#include <windows.h>
#include "cardlib.h"
#include "cardregion.h"
#include "cardcolor.h"

HPALETTE UseNicePalette(HDC hdc, HPALETTE hPalette);
void PaintRect(HDC hdc, RECT *rect, COLORREF colour);
void CardBlt(HDC hdc, int x, int y, int nCardNum);
void DrawCard(HDC hdc, int x, int y, HDC hdcSource, int width, int height);

//
//    Draw specified card at position x, y
//    xoff   - source offset from left of card
//    yoff   - source offset from top of card
//    width  - width to draw
//    height - height to draw
//
void CardBlt(HDC hdc, int x, int y, int nCardNum)//, int xoff, int yoff, int width, int height)
{
    int sx = nCardNum * __cardwidth;
    int sy = 0;
    int width  = __cardwidth;
    int height = __cardheight;

    //draw main center band
    BitBlt(hdc, x+2, y, width - 4, height, __hdcCardBitmaps, sx+2, sy+0, SRCCOPY);

    //draw the two bits to the left
    BitBlt(hdc, x,   y+2, 1, height - 4, __hdcCardBitmaps, sx+0, sy+2, SRCCOPY);
    BitBlt(hdc, x+1, y+1, 1, height - 2, __hdcCardBitmaps, sx+1, sy+1, SRCCOPY);

    //draw the two bits to the right
    BitBlt(hdc, x+width-2, y+1, 1, height - 2, __hdcCardBitmaps, sx+width-2, sy+1, SRCCOPY);
    BitBlt(hdc, x+width-1, y+2, 1, height - 4, __hdcCardBitmaps, sx+width-1, sy+2, SRCCOPY);
}

//
//    Draw a shape this this:
//
//   ++++++++++++
//  ++++++++++++++
// ++            ++
//
void DrawHorzCardStrip(HDC hdc, int x, int y, int nCardNum, int height, BOOL fDrawTips)
{
    int sx  = nCardNum * __cardwidth;
    int sy  = 0;
    int one = 1;
    int two = 2;
    BOOL tips = fDrawTips ? FALSE : TRUE;

    if(height == 0) return;

    if(height < 0)
    {
        sy = sy + __cardheight;
        y  -= height;
        one = -one;
        two = -two;
    }

    // draw the main vertical band
    //
    BitBlt(hdc, x + 2, y, __cardwidth - 4, height, __hdcCardBitmaps, sx+2, sy, SRCCOPY);

    //if(height <= 1) return;

    // draw the "lips" at the left and right
    BitBlt(hdc, x+1,             y+one, 1, height-one*tips, __hdcCardBitmaps, sx+1,             sy+one, SRCCOPY);
    BitBlt(hdc, x+__cardwidth-2, y+one, 1, height-one*tips, __hdcCardBitmaps, sx+__cardwidth-2, sy+one, SRCCOPY);

    //if(height <= 2) return;

    // draw the outer-most lips
    BitBlt(hdc, x,               y+two, 1, height-two*tips, __hdcCardBitmaps, sx,               sy+two, SRCCOPY);
    BitBlt(hdc, x+__cardwidth-1, y+two, 1, height-two*tips, __hdcCardBitmaps, sx+__cardwidth-1, sy+two, SRCCOPY);    
}

//
//    Draw a shape like this:
//
//     +++
//      +++
//   +++
//   +++
//   +++
//   +++
//   +++
//   +++
//    +++
//     +++
//
//
void DrawVertCardStrip(HDC hdc, int x, int y, int nCardNum, int width, BOOL fDrawTips)
{
    int sx  = nCardNum * __cardwidth;
    int sy  = 0;
    int one = 1;
    int two = 2;
    BOOL tips = fDrawTips ? FALSE : TRUE;

    if(width == 0) return;
    

    if(width < 0)
    {
        sx = sx + __cardwidth;
        x  -= width;
        one = -1;
        two = -2;
    }

    // draw the main vertical band
    //
    BitBlt(hdc, x, y + 2, width, __cardheight - 4, __hdcCardBitmaps, sx, sy+2, SRCCOPY);

    //if(width <= 1) return;

    // draw the "lips" at the top and bottom
    BitBlt(hdc, x+one, y+1,              width-one*tips, 1, __hdcCardBitmaps, sx+one, sy + 1,              SRCCOPY);
    BitBlt(hdc, x+one, y+__cardheight-2, width-one*tips, 1, __hdcCardBitmaps, sx+one, sy + __cardheight-2, SRCCOPY);

    //if(width <= 2) return;

    // draw the outer-most lips
    BitBlt(hdc, x+two, y,                width-two*tips, 1, __hdcCardBitmaps, sx+two, sy,                  SRCCOPY);
    BitBlt(hdc, x+two, y+__cardheight-1, width-two*tips, 1, __hdcCardBitmaps, sx+two, sy + __cardheight-1, SRCCOPY);
}

//
//    xdir -   <0 or >0
//    ydir -   <0 or >0
//
void DrawCardCorner(HDC hdc, int x, int y, int cardval, int xdir, int ydir)
{
    int sx = cardval * __cardwidth;
    int sy = 0;

    HDC hdcSource = __hdcCardBitmaps;

    if(xdir < 0) 
    {
        x  += __cardwidth + xdir - 1;
        sx += __cardwidth + xdir - 1;
    }
    else
    {
        x  += xdir;
        sx += xdir;
    }

    if(ydir < 0) 
    {
        y  += __cardheight + ydir - 1;
        sy += __cardheight + ydir - 1;
    }
    else
    {
        y  += ydir;
        sy += ydir;
    }

    //convert x,y directions to -1, +1
    xdir = xdir < 0 ? -1 : 1;
    ydir = ydir < 0 ? -1 : 1;

    SetPixel(hdc, x+xdir, y ,     GetPixel(hdcSource, sx+xdir, sy));
    SetPixel(hdc, x,      y,      GetPixel(hdcSource, sx,      sy));
    SetPixel(hdc, x,      y+ydir, GetPixel(hdcSource, sx,      sy+ydir));

}

//
//    Draw a card (i.e. miss out the corners)
//
void DrawCard(HDC hdc, int x, int y, HDC hdcDragCard, int width, int height)
{
    //draw main center band
    BitBlt(hdc, x+2, y, width - 4, height, hdcDragCard, 2, 0, SRCCOPY);

    //draw the two bits to the left
    BitBlt(hdc, x,   y+2, 1, height - 4, hdcDragCard, 0, 2, SRCCOPY);
    BitBlt(hdc, x+1, y+1, 1, height - 2, hdcDragCard, 1, 1, SRCCOPY);

    //draw the two bits to the right
    BitBlt(hdc, x+width-2, y+1, 1, height - 2, hdcDragCard, width-2, 1, SRCCOPY);
    BitBlt(hdc, x+width-1, y+2, 1, height - 4, hdcDragCard, width-1, 2, SRCCOPY);
}

//
//    Clip a card SHAPE - basically any rectangle
//  with rounded corners
//
int ClipCard(HDC hdc, int x, int y, int width, int height)
{
    ExcludeClipRect(hdc, x+2,        y,     x+2+width-4, y+  height);
    ExcludeClipRect(hdc, x,            y+2, x+1,          y+2+height-4);
    ExcludeClipRect(hdc, x+1,        y+1, x+2,          y+1+height-2);
    ExcludeClipRect(hdc, x+width-2, y+1, x+width-2+1, y+1+height-2);
    ExcludeClipRect(hdc, x+width-1, y+2, x+width-1+1, y+2+height-4);
    return 0;
}

void CardRegion::Clip(HDC hdc)
{
    int numtoclip;

    if(fVisible == false) 
        return;

    Update();                //Update this stack's size+card count
    numtoclip = nNumApparentCards;

    //if we are making this stack flash on/off, then only 
    //clip the stack for drawing if the flash is in its ON state
    if(nFlashCount != 0)
    {
        if(fFlashVisible == FALSE)
            numtoclip = 0;
    }

    //if offset along a diagonal
    if(xoffset != 0 && yoffset != 0 && cardstack.NumCards() != 0)
    {
        for(int j = 0; j < numtoclip; j ++)
        {    
            ClipCard(hdc, xpos + xoffset * j, ypos + yoffset * j, __cardwidth, __cardheight);
        }    
    }
    //otherwise if just offset along a horizontal/vertical axis
    else
    {
        if(yoffset < 0 && numtoclip > 0)
        {
            ClipCard(hdc, xpos, ypos-((numtoclip-1)*-yoffset), width, height);
        }
        else if(xoffset < 0 && numtoclip > 0)
        {
            ClipCard(hdc, xpos-((numtoclip-1)*-xoffset), ypos, width, height);
        }
        else
        {
            ClipCard(hdc, xpos, ypos, width, height);
        }
    }

}

void CardRegion::Render(HDC hdc)
{
    int cardnum = 0;
    int numtodraw;
    BOOL fDrawTips;
    
    Update();            //Update this stack's card count + size

    numtodraw = nNumApparentCards;

    if(nFlashCount != 0)
    {
        if(fFlashVisible == false)
            numtodraw = 0;
    }

    if(fVisible == 0) return;
    
    cardnum = cardstack.NumCards() - numtodraw;
    int counter;

    for(counter = 0; counter < numtodraw; counter++)
    {
        int cardval;
        
        int x = xoffset * counter + xpos;
        int y = yoffset * counter + ypos;

        //if about to draw last card, then actually draw the top card
        if(counter == numtodraw - 1) cardnum = cardstack.NumCards() - 1;
        
        Card card = cardstack.cardlist[cardnum];
        cardval = card.Idx();
        
        if(card.FaceDown())
            cardval = nBackCardIdx;    //card-back
            
        //only draw the visible part of the card
        if(counter < numtodraw - 1)
        {
            if(yoffset != 0 && xoffset != 0)
                fDrawTips = FALSE;
            else
                fDrawTips = TRUE;

            if(yoffset != 0 && abs(xoffset) == 1 ||    xoffset != 0 && abs(yoffset) == 1)
                fDrawTips = TRUE;

            //draw horizontal strips
            if(yoffset > 0) 
            {
                DrawHorzCardStrip(hdc, x, y, cardval, yoffset, fDrawTips);
            }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?