make the Pen/Brush code backward compatible as discussed on wx-dev; marked the blocks...
[wxWidgets.git] / src / os2 / brush.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/brush.cpp
3 // Purpose: wxBrush
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/13/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifndef WX_PRECOMP
16 #include <stdio.h>
17 #include "wx/list.h"
18 #include "wx/utils.h"
19 #include "wx/app.h"
20 #include "wx/brush.h"
21 #include "wx/log.h"
22 #endif
23
24 #include "wx/os2/private.h"
25
26 #include "assert.h"
27
28 IMPLEMENT_DYNAMIC_CLASS(wxBrush, wxGDIObject)
29
30 wxBrushRefData::wxBrushRefData()
31 {
32 m_nStyle = wxSOLID;
33 m_hBrush = 0;
34 memset(&m_vBundle, '\0', sizeof(AREABUNDLE));
35 } // end of wxBrushRefData::wxBrushRefData
36
37 wxBrushRefData::wxBrushRefData(const wxBrushRefData& rData)
38 {
39 m_nStyle = rData.m_nStyle;
40 m_vStipple = rData.m_vStipple;
41 m_vColour = rData.m_vColour;
42 m_hBrush = 0;
43 memcpy(&m_vBundle, &rData.m_vBundle, sizeof(AREABUNDLE));
44 } // end of wxBrushRefData::wxBrushRefData
45
46 wxBrushRefData::~wxBrushRefData()
47 {
48 } // end of wxBrushRefData::~wxBrushRefData
49
50 //
51 // Brushes
52 //
53 wxBrush::wxBrush()
54 {
55 } // end of wxBrush::wxBrush
56
57 wxBrush::~wxBrush()
58 {
59 } // end of wxBrush::~wxBrush
60
61 wxBrush::wxBrush(
62 const wxColour& rColour
63 , wxBrushStyle nStyle
64 )
65 {
66 m_refData = new wxBrushRefData;
67
68 M_BRUSHDATA->m_vColour = rColour;
69 M_BRUSHDATA->m_nStyle = nStyle;
70 M_BRUSHDATA->m_hBrush = 0;
71 memset(&M_BRUSHDATA->m_vBundle, '\0', sizeof(AREABUNDLE));
72
73 RealizeResource();
74 } // end of wxBrush::wxBrush
75
76 #if FUTURE_WXWIN_COMPATIBILITY_3_0
77 wxBrush::wxBrush(const wxColour& col, int style)
78 {
79 m_refData = new wxBrushRefData;
80
81 M_BRUSHDATA->m_vColour = col;
82 M_BRUSHDATA->m_nStyle = (wxBrushStyle)style;
83 M_BRUSHDATA->m_hBrush = 0;
84 memset(&M_BRUSHDATA->m_vBundle, '\0', sizeof(AREABUNDLE));
85
86 RealizeResource();
87 }
88 #endif
89
90 wxBrush::wxBrush(const wxBitmap& rStipple)
91 {
92 m_refData = new wxBrushRefData;
93
94 M_BRUSHDATA->m_nStyle = wxSTIPPLE;
95 M_BRUSHDATA->m_vStipple = rStipple;
96 M_BRUSHDATA->m_hBrush = 0;
97 memset(&M_BRUSHDATA->m_vBundle, '\0', sizeof(AREABUNDLE));
98
99 RealizeResource();
100 } // end of wxBrush::wxBrush
101
102 bool wxBrush::RealizeResource()
103 {
104 bool bOk;
105 ERRORID vError;
106 wxString sError;
107
108 if (M_BRUSHDATA && M_BRUSHDATA->m_hBrush == 0L)
109 {
110 SIZEL vSize = {0, 0};
111 DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
112 HDC hDC = ::DevOpenDC( vHabmain
113 ,OD_MEMORY
114 ,"*"
115 ,5L
116 ,(PDEVOPENDATA)&vDop
117 ,NULLHANDLE
118 );
119 M_BRUSHDATA->m_hBrush = (WXHPEN)::GpiCreatePS( vHabmain
120 ,hDC
121 ,&vSize
122 ,PU_PELS | GPIT_MICRO | GPIA_ASSOC
123 );
124 }
125 if (M_BRUSHDATA)
126 {
127 //
128 // Set the color table to RGB mode
129 //
130 if (!::GpiCreateLogColorTable( (HPS)M_BRUSHDATA->m_hBrush
131 ,0L
132 ,LCOLF_RGB
133 ,0L
134 ,0L
135 ,NULL
136 ))
137 {
138 vError = ::WinGetLastError(vHabmain);
139 sError = wxPMErrorToStr(vError);
140 wxLogError(_T("Unable to set current color table to RGB mode. Error: %s\n"), sError.c_str());
141 return false;
142 }
143
144 if (M_BRUSHDATA->m_nStyle==wxTRANSPARENT)
145 {
146 return true;
147 }
148 COLORREF vPmColour = 0L;
149
150 vPmColour = M_BRUSHDATA->m_vColour.GetPixel() ;
151
152 M_BRUSHDATA->m_vBundle.usSet = LCID_DEFAULT;
153 switch (M_BRUSHDATA->m_nStyle)
154 {
155 case wxTRANSPARENT:
156 M_BRUSHDATA->m_hBrush = NULL; // Must always select a suitable background brush
157 break; // - could choose white always for a quick solution
158
159 case wxBDIAGONAL_HATCH:
160 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_DIAG3;
161 break;
162
163 case wxCROSSDIAG_HATCH:
164 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_DIAGHATCH;
165 break;
166
167 case wxFDIAGONAL_HATCH:
168 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_DIAG1;
169 break;
170
171 case wxCROSS_HATCH:
172 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_HATCH;
173 break;
174
175 case wxHORIZONTAL_HATCH:
176 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_HORIZ;
177 break;
178
179 case wxVERTICAL_HATCH:
180 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_VERT;
181 break;
182
183 case wxSTIPPLE:
184 if (M_BRUSHDATA->m_vStipple.Ok())
185 {
186 ::GpiSetBitmapId( M_BRUSHDATA->m_hBrush
187 ,(USHORT)M_BRUSHDATA->m_vStipple.GetHBITMAP()
188 ,(USHORT)M_BRUSHDATA->m_vStipple.GetId()
189 );
190 ::GpiSetPatternSet( M_BRUSHDATA->m_hBrush
191 ,(USHORT)M_BRUSHDATA->m_vStipple.GetId()
192 );
193 }
194 else
195 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_SOLID;
196 break ;
197
198 case wxSOLID:
199 default:
200 M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_SOLID;
201 break;
202 }
203 #ifdef WXDEBUG_CREATE
204 if (M_BRUSHDATA->m_hBrush==NULL) wxError("Cannot create brush","Internal error") ;
205 #endif
206 M_BRUSHDATA->m_vBundle.lColor = vPmColour;
207 M_BRUSHDATA->m_vBundle.lBackColor = RGB_WHITE;
208 M_BRUSHDATA->m_vBundle.usMixMode = FM_OVERPAINT;
209 M_BRUSHDATA->m_vBundle.usBackMixMode = BM_OVERPAINT;
210
211 bOk = (bool)::GpiSetAttrs( M_BRUSHDATA->m_hBrush
212 ,PRIM_AREA
213 ,ABB_COLOR | ABB_BACK_COLOR | ABB_MIX_MODE | ABB_BACK_MIX_MODE |
214 ABB_SET | ABB_SYMBOL | ABB_REF_POINT
215 ,ABB_SET | ABB_SYMBOL | ABB_REF_POINT
216 ,&M_BRUSHDATA->m_vBundle
217 );
218 if (!bOk)
219 {
220 vError = ::WinGetLastError(vHabmain);
221 sError = wxPMErrorToStr(vError);
222 wxLogError(_T("Can't set Gpi attributes for an AREABUNDLE. Error: %s\n"), sError.c_str());
223 }
224 return bOk;
225 }
226 return false;
227 } // end of wxBrush::RealizeResource
228
229 WXHANDLE wxBrush::GetResourceHandle() const
230 {
231 if (!M_BRUSHDATA)
232 return 0;
233 return (WXHANDLE)M_BRUSHDATA->m_hBrush;
234 } // end of wxBrush::GetResourceHandle
235
236 bool wxBrush::FreeResource( bool WXUNUSED(bForce) )
237 {
238 if (M_BRUSHDATA && (M_BRUSHDATA->m_hBrush != 0))
239 {
240 M_BRUSHDATA->m_hBrush = 0;
241 return true;
242 }
243 else return false;
244 } // end of wxBrush::FreeResource
245
246 bool wxBrush::IsFree() const
247 {
248 return (M_BRUSHDATA && (M_BRUSHDATA->m_hBrush == 0));
249 } // end of wxBrush::IsFree
250
251 void wxBrush::SetColour( const wxColour& rColour )
252 {
253 AllocExclusive();
254 M_BRUSHDATA->m_vColour = rColour;
255 RealizeResource();
256 }
257
258 void wxBrush::SetColour(unsigned char cRed, unsigned char cGreen, unsigned char cBlue)
259 {
260 AllocExclusive();
261 M_BRUSHDATA->m_vColour.Set( cRed, cGreen, cBlue );
262 RealizeResource();
263 } // end of wxBrush::SetColour
264
265 void wxBrush::SetStyle(wxBrushStyle nStyle)
266 {
267 AllocExclusive();
268 M_BRUSHDATA->m_nStyle = nStyle;
269 RealizeResource();
270 } // end of wxBrush::SetStyle
271
272 void wxBrush::SetStipple(
273 const wxBitmap& rStipple
274 )
275 {
276 AllocExclusive();
277 M_BRUSHDATA->m_vStipple = rStipple;
278 RealizeResource();
279 } // end of wxBrush::SetStipple
280
281 void wxBrush::SetPS(
282 HPS hPS
283 )
284 {
285 AllocExclusive();
286 if (M_BRUSHDATA->m_hBrush)
287 ::GpiDestroyPS(M_BRUSHDATA->m_hBrush);
288 M_BRUSHDATA->m_hBrush = hPS;
289 RealizeResource();
290 } // end of WxWinGdi_CPen::SetPS
291
292
293 bool wxBrush::operator == (
294 const wxBrush& brush
295 ) const
296 {
297 if (m_refData == brush.m_refData) return true;
298
299 if (!m_refData || !brush.m_refData) return false;
300
301 return ( *(wxBrushRefData*)m_refData == *(wxBrushRefData*)brush.m_refData );
302 } // end of wxBrush::operator ==
303
304 wxGDIRefData *wxBrush::CreateGDIRefData() const
305 {
306 return new wxBrushRefData;
307 }
308
309 wxGDIRefData *wxBrush::CloneGDIRefData(const wxGDIRefData *data) const
310 {
311 return new wxBrushRefData(*(const wxBrushRefData *)data);
312 }