]>
Commit | Line | Data |
---|---|---|
0e320a79 DW |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: dcmemory.cpp | |
3 | // Purpose: wxMemoryDC class | |
fb46a9a6 | 4 | // Author: David Webster |
0e320a79 | 5 | // Modified by: |
fb46a9a6 | 6 | // Created: 10/14/99 |
0e320a79 | 7 | // RCS-ID: $Id$ |
fb46a9a6 DW |
8 | // Copyright: (c) David Webster |
9 | // Licence: wxWindows licence | |
0e320a79 DW |
10 | ///////////////////////////////////////////////////////////////////////////// |
11 | ||
fb46a9a6 DW |
12 | // For compilers that support precompilation, includes "wx.h". |
13 | #include "wx/wxprec.h" | |
14 | ||
15 | #ifndef WX_PRECOMP | |
16 | #include "wx/utils.h" | |
3417f661 SN |
17 | #include "wx/app.h" |
18 | #include "wx/log.h" | |
0e320a79 DW |
19 | #endif |
20 | ||
fb46a9a6 DW |
21 | #include "wx/os2/private.h" |
22 | ||
0e320a79 DW |
23 | #include "wx/dcmemory.h" |
24 | ||
fb46a9a6 | 25 | IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC, wxDC) |
0e320a79 | 26 | |
52315bc3 DW |
27 | extern void wxLoadBitmapWithData( HPS hPS |
28 | ,HBITMAP hBitmap | |
29 | ,int nWidth | |
30 | ,int nHeight | |
31 | ); | |
32 | ||
23122f8c DW |
33 | ///////////////////////////////////////////////////////////////////////////// |
34 | // Memory DC | |
35 | ///////////////////////////////////////////////////////////////////////////// | |
0e320a79 DW |
36 | |
37 | wxMemoryDC::wxMemoryDC(void) | |
38 | { | |
e1a688e4 DW |
39 | CreateCompatible(NULL); |
40 | Init(); | |
23122f8c DW |
41 | } // end of wxMemoryDC::wxMemoryDC |
42 | ||
43 | wxMemoryDC::wxMemoryDC( | |
44 | wxDC* pOldDC | |
45 | ) | |
e1a688e4 DW |
46 | { |
47 | pOldDC->BeginDrawing(); | |
48 | CreateCompatible(pOldDC); | |
49 | pOldDC->EndDrawing(); | |
50 | Init(); | |
51 | } // end of wxMemoryDC::wxMemoryDC | |
52 | ||
53 | void wxMemoryDC::Init() | |
54 | { | |
55 | if (m_ok) | |
56 | { | |
57 | SetBrush(*wxWHITE_BRUSH); | |
58 | SetPen(*wxBLACK_PEN); | |
59 | ||
60 | // the background mode is only used for text background and is set in | |
61 | // DrawText() to OPAQUE as required, otherwise always TRANSPARENT | |
62 | ::GpiSetBackMix( GetHPS(), BM_LEAVEALONE ); | |
63 | } | |
1d0edc0f | 64 | memset(&m_vRclPaint, 0, sizeof(m_vRclPaint)); |
e1a688e4 DW |
65 | } // end of wxMemoryDC::Init |
66 | ||
67 | bool wxMemoryDC::CreateCompatible( | |
68 | wxDC* pDC | |
69 | ) | |
0e320a79 | 70 | { |
23122f8c DW |
71 | HDC hDC; |
72 | HPS hPS; | |
73 | DEVOPENSTRUC vDOP = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L}; | |
74 | SIZEL vSize = {0, 0}; | |
75 | ||
23122f8c DW |
76 | // |
77 | // Create a memory device context | |
78 | // | |
e1a688e4 | 79 | hDC = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDOP, NULLHANDLE); |
23122f8c DW |
80 | if (hDC != DEV_ERROR) |
81 | { | |
82 | hPS = ::GpiCreatePS(vHabmain, hDC, &vSize, PU_PELS | GPIT_MICRO | GPIA_ASSOC); | |
83 | if (hPS != GPI_ERROR) | |
84 | { | |
85 | m_hPS = hPS; | |
86 | m_hDC = hDC; | |
87 | m_ok = TRUE; | |
88 | m_bOwnsDC = TRUE; | |
e1a688e4 DW |
89 | // |
90 | // Set the wxWindows color table | |
91 | // | |
92 | ::GpiCreateLogColorTable( m_hPS | |
93 | ,0L | |
94 | ,LCOLF_CONSECRGB | |
95 | ,0L | |
96 | ,(LONG)wxTheColourDatabase->m_nSize | |
97 | ,(PLONG)wxTheColourDatabase->m_palTable | |
98 | ); | |
99 | ::GpiCreateLogColorTable( m_hPS | |
100 | ,0L | |
101 | ,LCOLF_RGB | |
102 | ,0L | |
103 | ,0L | |
104 | ,NULL | |
105 | ); | |
23122f8c DW |
106 | } |
107 | else | |
108 | { | |
23122f8c DW |
109 | m_hPS = NULLHANDLE; |
110 | m_hDC = NULLHANDLE; | |
111 | m_ok = FALSE; | |
112 | m_bOwnsDC = FALSE; | |
113 | } | |
114 | } | |
115 | else | |
116 | { | |
23122f8c DW |
117 | m_hPS = NULLHANDLE; |
118 | m_hDC = NULLHANDLE; | |
119 | m_ok = FALSE; | |
120 | m_bOwnsDC = FALSE; | |
121 | } | |
23122f8c | 122 | |
e1a688e4 DW |
123 | // |
124 | // As we created the DC, we must delete it in the dtor | |
125 | // | |
126 | m_bOwnsDC = TRUE; | |
127 | m_ok = m_hDC != 0; | |
128 | return m_ok; | |
129 | } // end of wxMemoryDC::CreateCompatible | |
23122f8c DW |
130 | |
131 | void wxMemoryDC::SelectObject( | |
132 | const wxBitmap& rBitmap | |
133 | ) | |
0e320a79 | 134 | { |
23122f8c DW |
135 | // |
136 | // Select old bitmap out of the device context | |
137 | // | |
138 | if (m_hOldBitmap) | |
139 | { | |
140 | ::GpiSetBitmap(m_hPS, NULLHANDLE); | |
141 | if (m_vSelectedBitmap.Ok()) | |
142 | { | |
143 | m_vSelectedBitmap.SetSelectedInto(NULL); | |
144 | m_vSelectedBitmap = wxNullBitmap; | |
145 | } | |
146 | } | |
147 | ||
148 | // | |
149 | // Check for whether the bitmap is already selected into a device context | |
150 | // | |
151 | wxCHECK_RET( !rBitmap.GetSelectedInto() || | |
152 | (rBitmap.GetSelectedInto() == this), | |
153 | wxT("Bitmap is selected in another wxMemoryDC, delete the first wxMemoryDC or use SelectObject(NULL)") ); | |
154 | ||
155 | m_vSelectedBitmap = rBitmap; | |
156 | ||
1d0edc0f | 157 | WXHBITMAP hBmp = rBitmap.GetHBITMAP(); |
23122f8c DW |
158 | |
159 | if (!hBmp) | |
160 | return; | |
161 | ||
162 | m_vSelectedBitmap.SetSelectedInto(this); | |
163 | hBmp = (WXHBITMAP)::GpiSetBitmap(m_hPS, (HBITMAP)hBmp); | |
164 | ||
5afb9458 | 165 | if (hBmp == HBM_ERROR) |
23122f8c DW |
166 | { |
167 | wxLogLastError(wxT("SelectObject(memDC, bitmap)")); | |
168 | wxFAIL_MSG(wxT("Couldn't select a bitmap into wxMemoryDC")); | |
169 | } | |
170 | else if (!m_hOldBitmap) | |
171 | { | |
172 | m_hOldBitmap = hBmp; | |
173 | } | |
174 | } // end of wxMemoryDC::SelectObject | |
175 | ||
176 | void wxMemoryDC::DoGetSize( | |
177 | int* pWidth | |
178 | , int* pHeight | |
179 | ) const | |
0e320a79 | 180 | { |
23122f8c DW |
181 | if (!m_vSelectedBitmap.Ok()) |
182 | { | |
183 | *pWidth = 0; | |
184 | *pHeight = 0; | |
185 | return; | |
186 | } | |
187 | *pWidth = m_vSelectedBitmap.GetWidth(); | |
188 | *pHeight = m_vSelectedBitmap.GetHeight(); | |
189 | } // end of wxMemoryDC::DoGetSize | |
0e320a79 | 190 | |
e1a688e4 DW |
191 | void wxMemoryDC::DoDrawRectangle( |
192 | wxCoord vX | |
193 | , wxCoord vY | |
194 | , wxCoord vWidth | |
195 | , wxCoord vHeight | |
196 | ) | |
197 | { | |
198 | wxDC::DoDrawRectangle(vX, vY, vWidth, vHeight); | |
1cee3f60 | 199 | |
52315bc3 DW |
200 | wxLoadBitmapWithData( m_hPS |
201 | ,(HBITMAP)m_vSelectedBitmap.GetHBITMAP() | |
202 | ,m_vSelectedBitmap.GetWidth() | |
203 | ,m_vSelectedBitmap.GetHeight() | |
204 | ); | |
ba3e10c9 DW |
205 | } // end of wxMemoryDC::DoDrawRectangle |
206 | ||
207 | void wxMemoryDC::DoDrawRoundedRectangle( | |
208 | wxCoord vX | |
209 | , wxCoord vY | |
210 | , wxCoord vWidth | |
211 | , wxCoord vHeight | |
212 | , double dRadius | |
213 | ) | |
214 | { | |
215 | wxDC::DoDrawRoundedRectangle(vX, vY, vWidth, vHeight, dRadius); | |
216 | ||
52315bc3 DW |
217 | wxLoadBitmapWithData( m_hPS |
218 | ,(HBITMAP)m_vSelectedBitmap.GetHBITMAP() | |
219 | ,m_vSelectedBitmap.GetWidth() | |
220 | ,m_vSelectedBitmap.GetHeight() | |
221 | ); | |
222 | } // end of wxMemoryDC::DoDrawRoundedRectangle | |
ba3e10c9 | 223 | |
52315bc3 DW |
224 | void wxMemoryDC::DoDrawText( |
225 | const wxString& rsText | |
226 | , wxCoord vX | |
227 | , wxCoord vY | |
228 | ) | |
229 | { | |
230 | wxDC::DoDrawText(rsText, vX, vY); | |
ba3e10c9 | 231 | |
52315bc3 DW |
232 | wxLoadBitmapWithData( m_hPS |
233 | ,(HBITMAP)m_vSelectedBitmap.GetHBITMAP() | |
234 | ,m_vSelectedBitmap.GetWidth() | |
235 | ,m_vSelectedBitmap.GetHeight() | |
236 | ); | |
237 | } // end of wxMemoryDC::DoDrawRectangle | |
238 | ||
239 | void wxMemoryDC::DoDrawLine( | |
240 | wxCoord vX1 | |
241 | , wxCoord vY1 | |
242 | , wxCoord vX2 | |
243 | , wxCoord vY2 | |
244 | ) | |
245 | { | |
246 | wxDC::DoDrawLine(vX1, vY1, vX2, vY2); | |
247 | ||
248 | wxLoadBitmapWithData( m_hPS | |
249 | ,(HBITMAP)m_vSelectedBitmap.GetHBITMAP() | |
250 | ,m_vSelectedBitmap.GetWidth() | |
251 | ,m_vSelectedBitmap.GetHeight() | |
252 | ); | |
253 | } // end of wxMemoryDC::DoDrawRoundedRectangle | |
254 | ||
255 | void wxLoadBitmapWithData( | |
256 | HPS hPS | |
257 | , HBITMAP hBitmap | |
258 | , int nWidth | |
259 | , int nHeight | |
260 | ) | |
261 | { | |
262 | BITMAPINFOHEADER2 vHeader; | |
263 | BITMAPINFO2 vInfo; | |
264 | ||
265 | vHeader.cbFix = 16L; | |
266 | if (::GpiQueryBitmapInfoHeader(hBitmap, &vHeader)) | |
267 | { | |
268 | unsigned char* pucData = NULL; | |
269 | unsigned char* pucBits; | |
270 | int nBytesPerLine = nWidth * 3; | |
271 | LONG lScans = 0L; | |
272 | POINTL vPoint; | |
273 | LONG lColor; | |
274 | ||
275 | vInfo.cbFix = 16; | |
276 | vInfo.cx = vHeader.cx; | |
277 | vInfo.cy = vHeader.cy; | |
278 | vInfo.cPlanes = vHeader.cPlanes; | |
279 | vInfo.cBitCount = 24; | |
280 | pucData = (unsigned char*)malloc(nBytesPerLine * nHeight); | |
281 | pucBits = pucData; | |
282 | for (int i = 0; i < nHeight; i++) | |
283 | { | |
284 | for (int j = 0; j < nWidth; j++) | |
ba3e10c9 | 285 | { |
52315bc3 DW |
286 | vPoint.x = j; vPoint.y = i; |
287 | lColor = ::GpiQueryPel(hPS, &vPoint); | |
288 | *(pucBits++) = (unsigned char)lColor; | |
289 | *(pucBits++) = (unsigned char)(lColor >> 8); | |
290 | *(pucBits++) = (unsigned char)(lColor >> 16); | |
1cee3f60 | 291 | } |
52315bc3 DW |
292 | } |
293 | if ((lScans = ::GpiSetBitmapBits( hPS | |
294 | ,0 | |
295 | ,(LONG)nHeight | |
296 | ,(PBYTE)pucData | |
297 | ,&vInfo | |
298 | )) == GPI_ALTERROR) | |
299 | { | |
300 | ERRORID vError; | |
301 | wxString sError; | |
1cee3f60 | 302 | |
52315bc3 DW |
303 | vError = ::WinGetLastError(vHabmain); |
304 | sError = wxPMErrorToStr(vError); | |
1cee3f60 | 305 | } |
52315bc3 | 306 | free(pucData); |
1cee3f60 | 307 | } |
52315bc3 | 308 | } |