win95-initial-port-20010430
[openafs.git] / src / WINNT / win9xpanel / Transbmp.cpp
1 /* Copyright 2000, International Business Machines Corporation and others.
2         All Rights Reserved.
3  
4         This software has been released under the terms of the IBM Public
5         License.  For details, see the LICENSE file in the top-level source
6         directory or online at http://www.openafs.org/dl/license10.html
7 */
8 #include "stdafx.h"
9 #include "transbmp.h"
10
11 #ifdef _DEBUG
12 #undef THIS_FILE
13 static char BASED_CODE THIS_FILE[] = __FILE__;
14 #endif
15
16 // Colors
17 #define rgbWhite RGB(255,255,255)
18 // Raster op codes
19 #define DSa     0x008800C6L
20 #define DSx     0x00660046L
21
22
23 CTransBmp::CTransBmp()
24 {
25     m_iWidth = 0;
26     m_iHeight = 0;
27     m_hbmMask = NULL;
28 }
29
30 CTransBmp::~CTransBmp()
31 {
32 }
33
34 void CTransBmp::GetMetrics()
35 {
36     // Get the width and height
37     BITMAP bm;
38     GetObject(sizeof(bm), &bm);
39     m_iWidth = bm.bmWidth;
40     m_iHeight = bm.bmHeight;
41 }
42
43
44 int CTransBmp::GetWidth()
45 {
46     if ((m_iWidth == 0) || (m_iHeight == 0)){
47         GetMetrics();
48     }
49     return m_iWidth;
50 }
51
52 int CTransBmp::GetHeight()
53 {
54     if ((m_iWidth == 0) || (m_iHeight == 0)){
55         GetMetrics();
56     }
57     return m_iHeight;
58 }
59
60 void CTransBmp::Draw(HDC hDC, int x, int y)
61 {
62     ASSERT(hDC);
63     HDC hdcMem = ::CreateCompatibleDC(hDC);
64     HBITMAP hbmold = 
65         (HBITMAP)::SelectObject(hdcMem,
66                                 (HBITMAP)(m_hObject));
67     // Blt the bits
68     ::BitBlt(hDC,
69              x, y,
70              GetWidth(), GetHeight(),
71              hdcMem,
72              0, 0,
73              SRCCOPY);
74     ::SelectObject(hdcMem, hbmold);
75     ::DeleteDC(hdcMem); 
76 }
77
78 void CTransBmp::Draw(CDC* pDC, int x, int y)
79 {
80     ASSERT(pDC);
81     HDC hDC = pDC->GetSafeHdc();
82     Draw(hDC, x, y);
83 }
84
85 void CTransBmp::UpdateMask(CWnd *wnd,CRect &rect)
86 {
87     if (m_hbmMask)
88         ::DeleteObject(m_hbmMask);
89         m_hbmMask=NULL;
90         wnd->InvalidateRect(rect,TRUE);
91 }
92
93 void CTransBmp::CreateMask(HDC hDC,CRect &rect,int xoff)
94 {
95     if (m_hbmMask) {
96         ::DeleteObject(m_hbmMask);
97     }
98     // Create memory DCs to work with
99     HDC hdcMask = ::CreateCompatibleDC(hDC);
100     HDC hdcImage = ::CreateCompatibleDC(hDC);
101     // Create a monochrome bitmap for the mask
102     m_hbmMask = ::CreateBitmap(rect.Width(),
103                                rect.Height(),
104                                1,
105                                1,
106                                NULL);
107     // Select the mono bitmap into its DC
108     HBITMAP hbmOldMask = (HBITMAP)::SelectObject(hdcMask, m_hbmMask);
109     // Select the image bitmap into its DC
110     HBITMAP hbmOldImage = (HBITMAP)::SelectObject(hdcImage, m_hObject);
111     // Set the transparency color to be the top-left pixel
112     ::SetBkColor(hdcImage, ::GetPixel(hdcImage, 0, 0));
113     // Make the mask
114     ::BitBlt(hdcMask,
115              0, 0,
116              rect.Width(), rect.Height(),
117              hdcImage,
118              xoff, 0,
119              SRCCOPY);
120     ::SelectObject(hdcMask, hbmOldMask);
121     ::SelectObject(hdcImage, hbmOldImage);
122     ::DeleteDC(hdcMask);
123     ::DeleteDC(hdcImage);
124 }
125
126 /*
127         X,Y Destaination location
128         w, destination width
129         xoff source offset
130 */
131 void CTransBmp::DrawTrans(HDC hDC, CRect &rect, int xoff)
132 {
133     ASSERT(hDC);
134     if (!m_hbmMask) CreateMask(hDC,rect,xoff);
135     ASSERT(m_hbmMask);
136     int dx = rect.Width();
137     int dy = rect.Height();
138
139     // Create a memory DC to do the drawing to
140     HDC hdcOffScr = ::CreateCompatibleDC(hDC);
141     // Create a bitmap for the off-screen DC that is really
142     // color compatible with the destination DC.
143     HBITMAP hbmOffScr = ::CreateBitmap(dx, dy, 
144                              (BYTE)GetDeviceCaps(hDC, PLANES),
145                              (BYTE)GetDeviceCaps(hDC, BITSPIXEL),
146                              NULL);
147     // Select the buffer bitmap into the off-screen DC
148     HBITMAP hbmOldOffScr = (HBITMAP)::SelectObject(hdcOffScr, hbmOffScr);
149
150     // Copy the image of the destination rectangle to the
151     // off-screen buffer DC so we can play with it
152     ::BitBlt(hdcOffScr, 0, 0, dx, dy, hDC, 0, 0, SRCCOPY);
153
154     // Create a memory DC for the source image
155     HDC hdcImage = ::CreateCompatibleDC(hDC); 
156     HBITMAP hbmOldImage = (HBITMAP)::SelectObject(hdcImage, m_hObject);
157
158     // Create a memory DC for the mask
159     HDC hdcMask = ::CreateCompatibleDC(hDC);
160     HBITMAP hbmOldMask = (HBITMAP)::SelectObject(hdcMask, m_hbmMask);
161
162     // XOR the image with the destination
163     ::SetBkColor(hdcOffScr,rgbWhite);
164     ::BitBlt(hdcOffScr, 0, 0, dx, dy ,hdcImage, xoff, 0, DSx);
165     // AND the destination with the mask
166     ::BitBlt(hdcOffScr, 0, 0, dx, dy, hdcMask, 0,0, DSa);
167     // XOR the destination with the image again
168     ::BitBlt(hdcOffScr, 0, 0, dx, dy, hdcImage, xoff, 0, DSx);
169
170     // Copy the resultant image back to the screen DC
171     ::BitBlt(hDC, rect.left, rect.top, dx, dy, hdcOffScr, 0, 0, SRCCOPY);
172
173     // Tidy up
174     ::SelectObject(hdcOffScr, hbmOldOffScr);
175     ::SelectObject(hdcImage, hbmOldImage);
176     ::SelectObject(hdcMask, hbmOldMask);
177     ::DeleteObject(hbmOffScr);
178     ::DeleteDC(hdcOffScr);
179     ::DeleteDC(hdcImage);
180     ::DeleteDC(hdcMask);
181 }
182
183 void CTransBmp::DrawTrans(CDC* pDC,CRect &rect, int xoff)
184 {
185     ASSERT(pDC);
186     HDC hDC = pDC->GetSafeHdc();
187     DrawTrans(hDC, rect,xoff);
188 }
189