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