home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / include / DDB.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-11  |  7.8 KB  |  291 lines

  1. //-----------------------------------------------------------------------------------//
  2. //              Windows Graphics Programming: Win32 GDI and DirectDraw               //
  3. //                             ISBN  0-13-086985-6                                   //
  4. //                                                                                   //
  5. //  Written            by  Yuan, Feng                             www.fengyuan.com   //
  6. //  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
  7. //  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
  8. //                                                                                   //
  9. //  FileName   : ddb.cpp                                                             //
  10. //  Description: Device Dependent Bitmap Wrapping Class                              //
  11. //  Version    : 1.00.000, May 31, 2000                                              //
  12. //-----------------------------------------------------------------------------------//
  13.  
  14. #define STRICT
  15. #define WIN32_LEAN_AND_MEAN
  16.  
  17. #include <windows.h>
  18. #include <assert.h>
  19. #include <tchar.h>
  20. #include <math.h>
  21.  
  22. #include "DDB.h"
  23.  
  24. // quey size, prepare memory DC, select bitmap into memory DC
  25. bool KDDB::Prepare(int & width, int & height)
  26. {
  27.     BITMAP bmp;
  28.  
  29.     if ( ! GetObject(m_hBitmap, sizeof(bmp), & bmp) )
  30.         return false;
  31.  
  32.     width  = bmp.bmWidth;
  33.     height = bmp.bmHeight;
  34.  
  35.     if ( m_hMemDC==NULL )    // ensure memdc is created
  36.     {
  37.         HDC hDC = GetDC(NULL);
  38.         m_hMemDC = CreateCompatibleDC(hDC);
  39.         ReleaseDC(NULL, hDC);
  40.  
  41.         m_hOldBmp = (HBITMAP) SelectObject(m_hMemDC, m_hBitmap);
  42.     }
  43.  
  44.     return true;
  45. }
  46.  
  47. // Convert color DDB into monochrome mask based on a back ground color
  48. HBITMAP KDDB::CreateMask(COLORREF crBackGround, HDC hMaskDC)
  49. {
  50.     int width, height;
  51.  
  52.     if ( ! Prepare(width, height) )
  53.         return NULL;
  54.  
  55.     HBITMAP hMask   = CreateBitmap(width, height, 1, 1, NULL);
  56.     HBITMAP hOld    = (HBITMAP) SelectObject(hMaskDC, hMask);
  57.  
  58.     SetBkColor(m_hMemDC, crBackGround);
  59.     BitBlt(hMaskDC, 0, 0, width, height, m_hMemDC, 0, 0, SRCCOPY);
  60.  
  61.     return hOld;
  62. }
  63.  
  64. // Relase resource
  65. void KDDB::ReleaseDDB(void)
  66. {
  67.     if ( m_hMemDC )
  68.     {
  69.         SelectObject(m_hMemDC, m_hOldBmp);
  70.         DeleteObject(m_hMemDC);
  71.         m_hMemDC = NULL;
  72.     }
  73.  
  74.     if ( m_hBitmap )
  75.     {
  76.         DeleteObject(m_hBitmap);
  77.         m_hBitmap = NULL;
  78.     }
  79.  
  80.     m_hOldBmp = NULL;
  81. }
  82.  
  83.  
  84. BOOL KDDB::Attach(HBITMAP hBmp)
  85. {
  86.     if ( hBmp==NULL )
  87.         return FALSE;
  88.  
  89.     if ( m_hOldBmp )    // deselected m_hBitmap
  90.     {
  91.         SelectObject(m_hMemDC, m_hOldBmp);
  92.         m_hOldBmp = NULL;
  93.     }
  94.  
  95.     if ( m_hBitmap )    // delete current bitmap
  96.         DeleteObject(m_hBitmap);
  97.  
  98.     m_hBitmap = hBmp;    // replace with new one
  99.  
  100.     if ( m_hMemDC )        // select if has memory DC
  101.     {
  102.         m_hOldBmp = (HBITMAP) SelectObject(m_hMemDC, m_hBitmap);
  103.         return m_hOldBmp != NULL;
  104.     }
  105.     else
  106.         return TRUE;
  107. }
  108.  
  109.  
  110. BOOL KDDB::Draw(HDC hDC, int x0, int y0, int w, int h, DWORD rop, int opt)
  111. {
  112.     int bmpwidth, bmpheight;
  113.  
  114.     if ( ! Prepare(bmpwidth, bmpheight) )
  115.         return FALSE;
  116.  
  117.     switch ( opt )
  118.     {
  119.         case draw_normal:
  120.             return BitBlt(hDC, x0, y0, bmpwidth, bmpheight, m_hMemDC, 0, 0, rop);
  121.  
  122.         case draw_center:
  123.             return BitBlt(hDC, x0 + (w-bmpwidth)/2, y0 + ( h-bmpheight)/2,
  124.                 bmpwidth, bmpheight, m_hMemDC, 0, 0, rop);
  125.             break;
  126.  
  127.         case draw_tile:
  128.         {
  129.             for (int j=0; j<h; j+= bmpheight)
  130.             for (int i=0; i<w; i+= bmpwidth)
  131.                 if ( ! BitBlt(hDC, x0+i, y0+j, bmpwidth, bmpheight, m_hMemDC, 0, 0, rop) )
  132.                     return FALSE;
  133.  
  134.             return TRUE;
  135.         }
  136.         break;
  137.  
  138.         case draw_stretch:
  139.             return StretchBlt(hDC, x0, y0, w, h, m_hMemDC, 0, 0, bmpwidth, bmpheight, rop);
  140.  
  141.         case draw_stretchprop:
  142.         {
  143.             int ww = w;
  144.             int hh = h;
  145.  
  146.             if ( w * bmpheight < h * bmpwidth )    // w/bmWidth is the mimimum scale
  147.                 hh = bmpheight * w / bmpwidth;
  148.             else
  149.                 ww = bmpwidth  * h / bmpheight;
  150.  
  151.             // propertional scaling and centering
  152.             return StretchBlt(hDC, x0 + (w-ww)/2, y0 + (h-hh)/2, ww, hh, m_hMemDC, 0, 0, bmpwidth, bmpheight, rop);
  153.         }
  154.  
  155.         default:
  156.             return FALSE;
  157.     }
  158. }
  159.  
  160. // Generate a text description of DDB format
  161. void DecodeDDB(HGDIOBJ hBmp, TCHAR mess[])
  162. {
  163.     BITMAP  bmp;
  164.  
  165.     if ( GetObject(hBmp, sizeof(bmp), & bmp) )
  166.     {
  167.         wsprintf(mess, _T("%dx%dx%dx%d w=%d, 0x%x"), bmp.bmWidth, bmp.bmHeight,
  168.             bmp.bmPlanes, bmp.bmBitsPixel, bmp.bmWidthBytes, bmp.bmBits);
  169.  
  170.         int size = bmp.bmWidthBytes * bmp.bmHeight;
  171.  
  172.         if ( size < 1024 )
  173.             wsprintf(mess+_tcslen(mess), _T(", %d b"), size);
  174.         else if ( size < 1024 * 1024 )
  175.             wsprintf(mess+_tcslen(mess), _T(", %d,%03d b"), size/1024, size%1024);
  176.         else
  177.             wsprintf(mess+_tcslen(mess), _T(", %d,%03d,%03d b"), size/1024/1024, size/1024%1024, size%1024);
  178.     }
  179.     else
  180.         _tcscpy(mess, _T("Failed"));
  181. }
  182.  
  183. // Search for the largest DDB compatible with a DC
  184. HBITMAP LargestDDB(HDC hDC)
  185. {
  186.     HBITMAP hBmp;
  187.  
  188.     int mins = 1;            // 1       pixel
  189.     int maxs = 1024 * 128;    // 16 Giga pixels
  190.  
  191.     while ( true ) // search for largest DDB
  192.     {
  193.         int mid = (mins + maxs)/2;
  194.  
  195.         hBmp = CreateCompatibleBitmap(hDC, mid, mid);
  196.  
  197.         if ( hBmp )
  198.         {
  199.             HBITMAP h = CreateCompatibleBitmap(hDC, mid+1, mid+1);
  200.  
  201.             if ( h==NULL )
  202.                 return hBmp;
  203.  
  204.             DeleteObject(h);
  205.             DeleteObject(hBmp);
  206.  
  207.             mins = mid+1;
  208.         }
  209.         else
  210.             maxs = mid;
  211.     }
  212.  
  213.     return NULL;
  214. }
  215.  
  216.  
  217. // Create a monochrome mask bitmap from a source DC
  218. BOOL KDDBMask::Create(HDC hDC, int nX, int nY, int nWidth, int nHeight, UINT crTransparent)
  219. {
  220.     Release();
  221.  
  222.     RECT rect = { nX, nY, nX + nWidth, nY + nHeight };
  223.     LPtoDP(hDC, (POINT *) & rect, 2);                                  
  224.     
  225.     m_nMaskWidth  = abs(rect.right - rect.left);
  226.     m_nMaskHeight = abs(rect.bottom - rect.top);                      // get real size
  227.  
  228.     m_hMemDC = CreateCompatibleDC(hDC);
  229.     m_hMask  = CreateBitmap(m_nMaskWidth, m_nMaskHeight, 1, 1, NULL); // monochrome bitmap
  230.     m_hOld   = (HBITMAP) SelectObject(m_hMemDC, m_hMask);
  231.  
  232.     COLORREF oldBk = SetBkColor(hDC, crTransparent);    // map crTransparent to 1, white
  233.     BOOL rslt = StretchBlt(m_hMemDC, 0, 0, m_nMaskWidth, m_nMaskHeight, hDC, nX, nY, nWidth, nHeight, SRCCOPY);
  234.     SetBkColor(hDC, oldBk);
  235.  
  236.     return rslt;
  237. }
  238.     
  239.  
  240. BOOL KDDBMask::ApplyMask(HDC hDC, int nX, int nY, int nWidth, int nHeight, DWORD rop)
  241. {
  242.     COLORREF oldFore = SetTextColor(hDC, RGB(0, 0, 0));            // Foreground Black
  243.     COLORREF oldBack = SetBkColor(hDC,   RGB(255, 255, 255));    // Background White
  244.  
  245.     BOOL rslt = StretchBlt(hDC, nX, nY, nWidth, nHeight, m_hMemDC, 0, 0, m_nMaskWidth, m_nMaskHeight, rop);
  246.  
  247.     SetTextColor(hDC, oldFore);
  248.     SetBkColor(hDC,   oldBack);
  249.  
  250.     return rslt;
  251. }
  252.  
  253.  
  254. // D=D^S, D=D & Mask, D=D^S    --> if (Mask==1) D else S
  255. BOOL KDDBMask::TransBlt(HDC hdcDest, int nDx0, int nDy0, int nDw, int nDh,
  256.                         HDC hdcSrc,  int nSx0, int nSy0, int nSw, int nSh)
  257. {
  258.     StretchBlt(hdcDest, nDx0, nDy0, nDw, nDh, hdcSrc, nSx0, nSy0, nSw, nSh, SRCINVERT);        // D^S
  259.     
  260.     ApplyMask(hdcDest, nDx0, nDy0, nDw, nDh, SRCAND);    // if trans D^S else 0
  261.  
  262.     return StretchBlt(hdcDest, nDx0, nDy0, nDw, nDh, hdcSrc, nSx0, nSy0, nSw, nSh, SRCINVERT);    // if trans D else S
  263. }
  264.  
  265.  
  266. BOOL KDDBMask::TransBlt_FlickFree(HDC hdcDest, int nDx0, int nDy0, int nDw, int nDh,
  267.                                   HDC hdcSrc,  int nSx0, int nSy0, int nSw, int nSh)
  268. {
  269.     StretchBlt(hdcSrc, nSx0, nSy0, nSw, nSh, 
  270.                hdcDest, nDx0, nDy0, nDw, nDh, SRCINVERT); // D^S
  271.  
  272.     ApplyMask(hdcSrc, nSx0, nSy0, nSw, nSh,    0x220000); // if trans 0 else D^S
  273.  
  274.     return StretchBlt(hdcDest, nDx0, nDy0, nDw, nDh,         // if trans D else S
  275.         hdcSrc, nSx0, nSy0, nSw, nSh, SRCINVERT);
  276. }
  277.  
  278.  
  279. BOOL G_TransparentBlt(HDC hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest,
  280.                     HDC hdcSrc,  int nXOriginSrc,  int nYOriginSrc,  int nWidthSrc,  int nHeightSrc,
  281.                     UINT crTransparent)
  282. {
  283.     KDDBMask mask;
  284.  
  285.     mask.Create(hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, crTransparent);
  286.  
  287.     return mask.TransBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
  288.                 hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc);
  289. }
  290.  
  291.