]>
Commit | Line | Data |
---|---|---|
1 | ///////////////////////////////////////////////////////////////////////////// | |
2 | // Name: src/os2/brush.cpp | |
3 | // Purpose: wxBrush | |
4 | // Author: David Webster | |
5 | // Modified by: | |
6 | // Created: 10/13/99 | |
7 | // Copyright: (c) David Webster | |
8 | // Licence: wxWindows licence | |
9 | ///////////////////////////////////////////////////////////////////////////// | |
10 | ||
11 | // For compilers that support precompilation, includes "wx.h". | |
12 | #include "wx/wxprec.h" | |
13 | ||
14 | #ifndef WX_PRECOMP | |
15 | #include <stdio.h> | |
16 | #include "wx/list.h" | |
17 | #include "wx/utils.h" | |
18 | #include "wx/app.h" | |
19 | #include "wx/brush.h" | |
20 | #include "wx/log.h" | |
21 | #endif | |
22 | ||
23 | #include "wx/os2/private.h" | |
24 | ||
25 | class WXDLLEXPORT wxBrushRefData: public wxGDIRefData | |
26 | { | |
27 | friend class WXDLLIMPEXP_FWD_CORE wxBrush; | |
28 | public: | |
29 | wxBrushRefData(const wxColour& colour = wxNullColour, wxBrushStyle style = wxBRUSHSTYLE_SOLID); | |
30 | wxBrushRefData(const wxBitmap& stipple); | |
31 | wxBrushRefData(const wxBrushRefData& rData); | |
32 | virtual ~wxBrushRefData(); | |
33 | ||
34 | bool operator == (const wxBrushRefData& data) const | |
35 | { | |
36 | return (m_nStyle == data.m_nStyle && | |
37 | m_vStipple.IsSameAs(data.m_vStipple) && | |
38 | m_vColour == data.m_vColour); | |
39 | } | |
40 | ||
41 | protected: | |
42 | wxBrushStyle m_nStyle; | |
43 | wxBitmap m_vStipple; | |
44 | wxColour m_vColour; | |
45 | WXHBRUSH m_hBrush; // in OS/2 GPI this will be the PS the pen is associated with | |
46 | AREABUNDLE m_vBundle; | |
47 | }; | |
48 | ||
49 | #define M_BRUSHDATA ((wxBrushRefData *)m_refData) | |
50 | ||
51 | // ============================================================================ | |
52 | // wxBrushRefData implementation | |
53 | // ============================================================================ | |
54 | ||
55 | IMPLEMENT_DYNAMIC_CLASS(wxBrush, wxGDIObject) | |
56 | ||
57 | // ---------------------------------------------------------------------------- | |
58 | // wxBrushRefData ctors/dtor | |
59 | // ---------------------------------------------------------------------------- | |
60 | ||
61 | wxBrushRefData::wxBrushRefData(const wxColour& colour, wxBrushStyle style) | |
62 | : m_vColour(colour) | |
63 | { | |
64 | m_nStyle = style; | |
65 | m_hBrush = 0; | |
66 | memset(&m_vBundle, '\0', sizeof(AREABUNDLE)); | |
67 | } // end of wxBrushRefData::wxBrushRefData | |
68 | ||
69 | wxBrushRefData::wxBrushRefData(const wxBitmap& stipple) | |
70 | { | |
71 | m_vStipple = stipple; | |
72 | m_nStyle = stipple.GetMask() ? wxBRUSHSTYLE_STIPPLE_MASK_OPAQUE | |
73 | : wxBRUSHSTYLE_STIPPLE; | |
74 | ||
75 | m_hBrush = NULL; | |
76 | memset(&m_vBundle, '\0', sizeof(AREABUNDLE)); | |
77 | } | |
78 | ||
79 | wxBrushRefData::wxBrushRefData(const wxBrushRefData& rData) | |
80 | : wxGDIRefData(), | |
81 | m_vStipple(rData.m_vStipple), | |
82 | m_vColour(rData.m_vColour) | |
83 | { | |
84 | m_nStyle = rData.m_nStyle; | |
85 | m_hBrush = 0; | |
86 | memcpy(&m_vBundle, &rData.m_vBundle, sizeof(AREABUNDLE)); | |
87 | } // end of wxBrushRefData::wxBrushRefData | |
88 | ||
89 | wxBrushRefData::~wxBrushRefData() | |
90 | { | |
91 | } // end of wxBrushRefData::~wxBrushRefData | |
92 | ||
93 | // ============================================================================ | |
94 | // wxBrush implementation | |
95 | // ============================================================================ | |
96 | ||
97 | // ---------------------------------------------------------------------------- | |
98 | // wxBrush ctors/dtor | |
99 | // ---------------------------------------------------------------------------- | |
100 | ||
101 | wxBrush::wxBrush() | |
102 | { | |
103 | } // end of wxBrush::wxBrush | |
104 | ||
105 | wxBrush::~wxBrush() | |
106 | { | |
107 | } // end of wxBrush::~wxBrush | |
108 | ||
109 | wxBrush::wxBrush( | |
110 | const wxColour& rColour | |
111 | , wxBrushStyle nStyle | |
112 | ) | |
113 | { | |
114 | m_refData = new wxBrushRefData(rColour, nStyle); | |
115 | ||
116 | RealizeResource(); | |
117 | } // end of wxBrush::wxBrush | |
118 | ||
119 | #if FUTURE_WXWIN_COMPATIBILITY_3_0 | |
120 | wxBrush::wxBrush(const wxColour& col, int style) | |
121 | { | |
122 | m_refData = new wxBrushRefData(col, (wxBrushStyle)style); | |
123 | ||
124 | RealizeResource(); | |
125 | } | |
126 | #endif | |
127 | ||
128 | wxBrush::wxBrush(const wxBitmap& rStipple) | |
129 | { | |
130 | m_refData = new wxBrushRefData(rStipple); | |
131 | ||
132 | RealizeResource(); | |
133 | } // end of wxBrush::wxBrush | |
134 | ||
135 | bool wxBrush::RealizeResource() | |
136 | { | |
137 | bool bOk; | |
138 | ERRORID vError; | |
139 | wxString sError; | |
140 | ||
141 | if (M_BRUSHDATA && M_BRUSHDATA->m_hBrush == 0L) | |
142 | { | |
143 | SIZEL vSize = {0, 0}; | |
144 | DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L}; | |
145 | HDC hDC = ::DevOpenDC( vHabmain | |
146 | ,OD_MEMORY | |
147 | ,"*" | |
148 | ,5L | |
149 | ,(PDEVOPENDATA)&vDop | |
150 | ,NULLHANDLE | |
151 | ); | |
152 | M_BRUSHDATA->m_hBrush = (WXHPEN)::GpiCreatePS( vHabmain | |
153 | ,hDC | |
154 | ,&vSize | |
155 | ,PU_PELS | GPIT_MICRO | GPIA_ASSOC | |
156 | ); | |
157 | } | |
158 | if (M_BRUSHDATA) | |
159 | { | |
160 | // | |
161 | // Set the color table to RGB mode | |
162 | // | |
163 | if (!::GpiCreateLogColorTable( (HPS)M_BRUSHDATA->m_hBrush | |
164 | ,0L | |
165 | ,LCOLF_RGB | |
166 | ,0L | |
167 | ,0L | |
168 | ,NULL | |
169 | )) | |
170 | { | |
171 | vError = ::WinGetLastError(vHabmain); | |
172 | sError = wxPMErrorToStr(vError); | |
173 | wxLogError(wxT("Unable to set current color table to RGB mode. Error: %s\n"), sError.c_str()); | |
174 | return false; | |
175 | } | |
176 | ||
177 | if (M_BRUSHDATA->m_nStyle==wxTRANSPARENT) | |
178 | { | |
179 | return true; | |
180 | } | |
181 | COLORREF vPmColour = 0L; | |
182 | ||
183 | vPmColour = M_BRUSHDATA->m_vColour.GetPixel() ; | |
184 | ||
185 | M_BRUSHDATA->m_vBundle.usSet = LCID_DEFAULT; | |
186 | switch (M_BRUSHDATA->m_nStyle) | |
187 | { | |
188 | case wxTRANSPARENT: | |
189 | M_BRUSHDATA->m_hBrush = NULL; // Must always select a suitable background brush | |
190 | break; // - could choose white always for a quick solution | |
191 | ||
192 | case wxBDIAGONAL_HATCH: | |
193 | M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_DIAG3; | |
194 | break; | |
195 | ||
196 | case wxCROSSDIAG_HATCH: | |
197 | M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_DIAGHATCH; | |
198 | break; | |
199 | ||
200 | case wxFDIAGONAL_HATCH: | |
201 | M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_DIAG1; | |
202 | break; | |
203 | ||
204 | case wxCROSS_HATCH: | |
205 | M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_HATCH; | |
206 | break; | |
207 | ||
208 | case wxHORIZONTAL_HATCH: | |
209 | M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_HORIZ; | |
210 | break; | |
211 | ||
212 | case wxVERTICAL_HATCH: | |
213 | M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_VERT; | |
214 | break; | |
215 | ||
216 | case wxSTIPPLE: | |
217 | if (M_BRUSHDATA->m_vStipple.IsOk()) | |
218 | { | |
219 | ::GpiSetBitmapId( M_BRUSHDATA->m_hBrush | |
220 | ,(USHORT)M_BRUSHDATA->m_vStipple.GetHBITMAP() | |
221 | ,(USHORT)M_BRUSHDATA->m_vStipple.GetId() | |
222 | ); | |
223 | ::GpiSetPatternSet( M_BRUSHDATA->m_hBrush | |
224 | ,(USHORT)M_BRUSHDATA->m_vStipple.GetId() | |
225 | ); | |
226 | } | |
227 | else | |
228 | M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_SOLID; | |
229 | break ; | |
230 | ||
231 | case wxSOLID: | |
232 | default: | |
233 | M_BRUSHDATA->m_vBundle.usSymbol = PATSYM_SOLID; | |
234 | break; | |
235 | } | |
236 | #ifdef WXDEBUG_CREATE | |
237 | if (M_BRUSHDATA->m_hBrush==NULL) wxError("Cannot create brush","Internal error") ; | |
238 | #endif | |
239 | M_BRUSHDATA->m_vBundle.lColor = vPmColour; | |
240 | M_BRUSHDATA->m_vBundle.lBackColor = RGB_WHITE; | |
241 | M_BRUSHDATA->m_vBundle.usMixMode = FM_OVERPAINT; | |
242 | M_BRUSHDATA->m_vBundle.usBackMixMode = BM_OVERPAINT; | |
243 | ||
244 | bOk = (bool)::GpiSetAttrs( M_BRUSHDATA->m_hBrush | |
245 | ,PRIM_AREA | |
246 | ,ABB_COLOR | ABB_BACK_COLOR | ABB_MIX_MODE | ABB_BACK_MIX_MODE | | |
247 | ABB_SET | ABB_SYMBOL | ABB_REF_POINT | |
248 | ,ABB_SET | ABB_SYMBOL | ABB_REF_POINT | |
249 | ,&M_BRUSHDATA->m_vBundle | |
250 | ); | |
251 | if (!bOk) | |
252 | { | |
253 | vError = ::WinGetLastError(vHabmain); | |
254 | sError = wxPMErrorToStr(vError); | |
255 | wxLogError(wxT("Can't set Gpi attributes for an AREABUNDLE. Error: %s\n"), sError.c_str()); | |
256 | } | |
257 | return bOk; | |
258 | } | |
259 | return false; | |
260 | } // end of wxBrush::RealizeResource | |
261 | ||
262 | // ---------------------------------------------------------------------------- | |
263 | // wxBrush accessors | |
264 | // ---------------------------------------------------------------------------- | |
265 | ||
266 | wxColour wxBrush::GetColour() const | |
267 | { | |
268 | wxCHECK_MSG( IsOk(), wxNullColour, wxT("invalid brush") ); | |
269 | ||
270 | return M_BRUSHDATA->m_vColour; | |
271 | } | |
272 | ||
273 | wxBrushStyle wxBrush::GetStyle() const | |
274 | { | |
275 | wxCHECK_MSG( IsOk(), wxBRUSHSTYLE_INVALID, wxT("invalid brush") ); | |
276 | ||
277 | return M_BRUSHDATA->m_nStyle; | |
278 | } | |
279 | ||
280 | wxBitmap *wxBrush::GetStipple() const | |
281 | { | |
282 | wxCHECK_MSG( IsOk(), NULL, wxT("invalid brush") ); | |
283 | ||
284 | return &(M_BRUSHDATA->m_vStipple); | |
285 | } | |
286 | ||
287 | int wxBrush::GetPS() const | |
288 | { | |
289 | wxCHECK_MSG( IsOk(), 0, wxT("invalid brush") ); | |
290 | ||
291 | return M_BRUSHDATA->m_hBrush; | |
292 | } | |
293 | ||
294 | WXHANDLE wxBrush::GetResourceHandle() const | |
295 | { | |
296 | wxCHECK_MSG( IsOk(), 0, wxT("invalid brush") ); | |
297 | ||
298 | return (WXHANDLE)M_BRUSHDATA->m_hBrush; | |
299 | } // end of wxBrush::GetResourceHandle | |
300 | ||
301 | bool wxBrush::FreeResource( bool WXUNUSED(bForce) ) | |
302 | { | |
303 | if (M_BRUSHDATA && (M_BRUSHDATA->m_hBrush != 0)) | |
304 | { | |
305 | M_BRUSHDATA->m_hBrush = 0; | |
306 | return true; | |
307 | } | |
308 | else return false; | |
309 | } // end of wxBrush::FreeResource | |
310 | ||
311 | bool wxBrush::IsFree() const | |
312 | { | |
313 | return (M_BRUSHDATA && (M_BRUSHDATA->m_hBrush == 0)); | |
314 | } // end of wxBrush::IsFree | |
315 | ||
316 | // ---------------------------------------------------------------------------- | |
317 | // wxBrush setters | |
318 | // ---------------------------------------------------------------------------- | |
319 | ||
320 | void wxBrush::SetColour( const wxColour& rColour ) | |
321 | { | |
322 | AllocExclusive(); | |
323 | M_BRUSHDATA->m_vColour = rColour; | |
324 | RealizeResource(); | |
325 | } | |
326 | ||
327 | void wxBrush::SetColour(unsigned char cRed, unsigned char cGreen, unsigned char cBlue) | |
328 | { | |
329 | AllocExclusive(); | |
330 | M_BRUSHDATA->m_vColour.Set( cRed, cGreen, cBlue ); | |
331 | RealizeResource(); | |
332 | } // end of wxBrush::SetColour | |
333 | ||
334 | void wxBrush::SetStyle(wxBrushStyle nStyle) | |
335 | { | |
336 | AllocExclusive(); | |
337 | M_BRUSHDATA->m_nStyle = nStyle; | |
338 | RealizeResource(); | |
339 | } // end of wxBrush::SetStyle | |
340 | ||
341 | void wxBrush::SetStipple( | |
342 | const wxBitmap& rStipple | |
343 | ) | |
344 | { | |
345 | AllocExclusive(); | |
346 | M_BRUSHDATA->m_vStipple = rStipple; | |
347 | RealizeResource(); | |
348 | } // end of wxBrush::SetStipple | |
349 | ||
350 | void wxBrush::SetPS( | |
351 | HPS hPS | |
352 | ) | |
353 | { | |
354 | AllocExclusive(); | |
355 | if (M_BRUSHDATA->m_hBrush) | |
356 | ::GpiDestroyPS(M_BRUSHDATA->m_hBrush); | |
357 | M_BRUSHDATA->m_hBrush = hPS; | |
358 | RealizeResource(); | |
359 | } // end of WxWinGdi_CPen::SetPS | |
360 | ||
361 | // ---------------------------------------------------------------------------- | |
362 | // wxBrush house keeping stuff | |
363 | // ---------------------------------------------------------------------------- | |
364 | ||
365 | bool wxBrush::operator == ( | |
366 | const wxBrush& brush | |
367 | ) const | |
368 | { | |
369 | if (m_refData == brush.m_refData) return true; | |
370 | ||
371 | if (!m_refData || !brush.m_refData) return false; | |
372 | ||
373 | return ( *(wxBrushRefData*)m_refData == *(wxBrushRefData*)brush.m_refData ); | |
374 | } // end of wxBrush::operator == | |
375 | ||
376 | wxGDIRefData *wxBrush::CreateGDIRefData() const | |
377 | { | |
378 | return new wxBrushRefData; | |
379 | } | |
380 | ||
381 | wxGDIRefData *wxBrush::CloneGDIRefData(const wxGDIRefData *data) const | |
382 | { | |
383 | return new wxBrushRefData(*(const wxBrushRefData *)data); | |
384 | } |