]> git.saurik.com Git - wxWidgets.git/blame - src/common/gdicmn.cpp
avoiding nesting dcs on the same window concurrently
[wxWidgets.git] / src / common / gdicmn.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
ca3e85cf 2// Name: src/common/gdicmn.cpp
c801d85f
KB
3// Purpose: Common GDI classes
4// Author: Julian Smart
5// Modified by:
6// Created: 01/02/97
7// RCS-ID: $Id$
55d99c7a 8// Copyright: (c) Julian Smart
65571936 9// Licence: wxWindows licence
c801d85f
KB
10/////////////////////////////////////////////////////////////////////////////
11
c801d85f
KB
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
670f9935 16 #pragma hdrstop
c801d85f
KB
17#endif
18
19#include "wx/gdicmn.h"
5819f832 20#include "wx/gdiobj.h"
e4db172a
WS
21
22#ifndef WX_PRECOMP
23 #include "wx/log.h"
f5590243 24 #include "wx/pen.h"
c64755ed 25 #include "wx/brush.h"
559a723c 26 #include "wx/palette.h"
923d28da 27 #include "wx/icon.h"
c8326d64 28 #include "wx/cursor.h"
9eddec69 29 #include "wx/settings.h"
0bca0373 30 #include "wx/bitmap.h"
7cf41a5d 31 #include "wx/colour.h"
48a1108e 32 #include "wx/font.h"
e4db172a
WS
33#endif
34
5819f832
VS
35
36IMPLEMENT_DYNAMIC_CLASS(wxGDIObject, wxObject)
37
38
e7445ff8
PC
39WXDLLIMPEXP_DATA_CORE(wxBrushList*) wxTheBrushList;
40WXDLLIMPEXP_DATA_CORE(wxFontList*) wxTheFontList;
41WXDLLIMPEXP_DATA_CORE(wxPenList*) wxThePenList;
42
43WXDLLIMPEXP_DATA_CORE(wxColourDatabase*) wxTheColourDatabase;
44
45WXDLLIMPEXP_DATA_CORE(wxBitmap) wxNullBitmap;
46WXDLLIMPEXP_DATA_CORE(wxBrush) wxNullBrush;
47WXDLLIMPEXP_DATA_CORE(wxColour) wxNullColour;
48WXDLLIMPEXP_DATA_CORE(wxCursor) wxNullCursor;
49WXDLLIMPEXP_DATA_CORE(wxFont) wxNullFont;
50WXDLLIMPEXP_DATA_CORE(wxIcon) wxNullIcon;
51WXDLLIMPEXP_DATA_CORE(wxPen) wxNullPen;
52#if wxUSE_PALETTE
53WXDLLIMPEXP_DATA_CORE(wxPalette) wxNullPalette;
46ccb510
JS
54#endif
55
e7445ff8
PC
56const wxSize wxDefaultSize(wxDefaultCoord, wxDefaultCoord);
57const wxPoint wxDefaultPosition(wxDefaultCoord, wxDefaultCoord);
7266b672 58
cb73e600
SC
59#if wxUSE_EXTENDED_RTTI
60
61// wxPoint
62
63template<> void wxStringReadValue(const wxString &s , wxPoint &data )
64{
5d3e7b52 65 wxSscanf(s, wxT("%d,%d"), &data.x , &data.y ) ;
cb73e600
SC
66}
67
68template<> void wxStringWriteValue(wxString &s , const wxPoint &data )
69{
5d3e7b52 70 s = wxString::Format(wxT("%d,%d"), data.x , data.y ) ;
cb73e600
SC
71}
72
8805dbab 73wxCUSTOM_TYPE_INFO(wxPoint, wxToStringConverter<wxPoint> , wxFromStringConverter<wxPoint>)
cb73e600
SC
74
75template<> void wxStringReadValue(const wxString &s , wxSize &data )
76{
5d3e7b52 77 wxSscanf(s, wxT("%d,%d"), &data.x , &data.y ) ;
cb73e600
SC
78}
79
80template<> void wxStringWriteValue(wxString &s , const wxSize &data )
81{
5d3e7b52 82 s = wxString::Format(wxT("%d,%d"), data.x , data.y ) ;
cb73e600
SC
83}
84
8805dbab 85wxCUSTOM_TYPE_INFO(wxSize, wxToStringConverter<wxSize> , wxFromStringConverter<wxSize>)
cb73e600
SC
86
87#endif
88
d7a7546b 89wxRect::wxRect(const wxPoint& point1, const wxPoint& point2)
c801d85f 90{
5d3e7b52
WS
91 x = point1.x;
92 y = point1.y;
93 width = point2.x - point1.x;
94 height = point2.y - point1.y;
8bbe427f 95
5d3e7b52
WS
96 if (width < 0)
97 {
98 width = -width;
99 x = point2.x;
100 }
101 width++;
8bbe427f 102
5d3e7b52
WS
103 if (height < 0)
104 {
105 height = -height;
106 y = point2.y;
107 }
108 height++;
c801d85f
KB
109}
110
a23fd0e1 111bool wxRect::operator==(const wxRect& rect) const
c801d85f 112{
5d3e7b52
WS
113 return ((x == rect.x) &&
114 (y == rect.y) &&
115 (width == rect.width) &&
116 (height == rect.height));
c801d85f
KB
117}
118
df83b840 119wxRect wxRect::operator+(const wxRect& rect) const
619d0528 120{
45816ddd
VZ
121 int x1 = wxMin(this->x, rect.x);
122 int y1 = wxMin(this->y, rect.y);
123 int y2 = wxMax(y+height, rect.height+rect.y);
124 int x2 = wxMax(x+width, rect.width+rect.x);
125 return wxRect(x1, y1, x2-x1, y2-y1);
dcb44466
JS
126}
127
df83b840
VZ
128wxRect& wxRect::Union(const wxRect& rect)
129{
c71ce675
VZ
130 // ignore empty rectangles: union with an empty rectangle shouldn't extend
131 // this one to (0, 0)
132 if ( !width || !height )
133 {
134 *this = rect;
135 }
136 else if ( rect.width && rect.height )
df83b840
VZ
137 {
138 int x1 = wxMin(x, rect.x);
139 int y1 = wxMin(y, rect.y);
140 int y2 = wxMax(y + height, rect.height + rect.y);
141 int x2 = wxMax(x + width, rect.width + rect.x);
142
143 x = x1;
144 y = y1;
145 width = x2 - x1;
146 height = y2 - y1;
147 }
c71ce675 148 //else: we're not empty and rect is empty
df83b840
VZ
149
150 return *this;
151}
152
1e6feb95
VZ
153wxRect& wxRect::Inflate(wxCoord dx, wxCoord dy)
154{
8673a125
VZ
155 if (-2*dx>width)
156 {
157 // Don't allow deflate to eat more width than we have,
158 // a well-defined rectangle cannot have negative width.
159 x+=width/2;
160 width=0;
161 }
162 else
163 {
164 // The inflate is valid.
165 x-=dx;
166 width+=2*dx;
167 }
168
169 if (-2*dy>height)
170 {
171 // Don't allow deflate to eat more height than we have,
172 // a well-defined rectangle cannot have negative height.
173 y+=height/2;
174 height=0;
175 }
176 else
177 {
178 // The inflate is valid.
179 y-=dy;
180 height+=2*dy;
181 }
1e6feb95
VZ
182
183 return *this;
184}
185
22a35096 186bool wxRect::Contains(int cx, int cy) const
dcb44466 187{
45816ddd
VZ
188 return ( (cx >= x) && (cy >= y)
189 && ((cy - y) < height)
190 && ((cx - x) < width)
191 );
dcb44466
JS
192}
193
22a35096 194bool wxRect::Contains(const wxRect& rect) const
869b59fc 195{
22a35096 196 return Contains(rect.GetTopLeft()) && Contains(rect.GetBottomRight());
869b59fc
VS
197}
198
1e6feb95
VZ
199wxRect& wxRect::Intersect(const wxRect& rect)
200{
201 int x2 = GetRight(),
202 y2 = GetBottom();
203
204 if ( x < rect.x )
205 x = rect.x;
206 if ( y < rect.y )
207 y = rect.y;
208 if ( x2 > rect.GetRight() )
209 x2 = rect.GetRight();
210 if ( y2 > rect.GetBottom() )
211 y2 = rect.GetBottom();
212
213 width = x2 - x + 1;
214 height = y2 - y + 1;
215
216 if ( width <= 0 || height <= 0 )
217 {
218 width =
219 height = 0;
220 }
221
222 return *this;
223}
224
225bool wxRect::Intersects(const wxRect& rect) const
226{
227 wxRect r = Intersect(rect);
228
229 // if there is no intersection, both width and height are 0
230 return r.width != 0;
231}
232
c50f92d0
VZ
233// ============================================================================
234// wxColourDatabase
235// ============================================================================
236
c50f92d0
VZ
237// ----------------------------------------------------------------------------
238// wxColourDatabase ctor/dtor
239// ----------------------------------------------------------------------------
222ed1d6
MB
240
241wxColourDatabase::wxColourDatabase ()
c801d85f 242{
c50f92d0
VZ
243 // will be created on demand in Initialize()
244 m_map = NULL;
c801d85f
KB
245}
246
6a6c0a8b 247wxColourDatabase::~wxColourDatabase ()
c801d85f 248{
c50f92d0
VZ
249 if ( m_map )
250 {
251 WX_CLEAR_HASH_MAP(wxStringToColourHashMap, *m_map);
252
253 delete m_map;
254 }
222ed1d6 255
19bf0c69
DW
256#ifdef __WXPM__
257 delete [] m_palTable;
258#endif
c801d85f
KB
259}
260
261// Colour database stuff
c50f92d0 262void wxColourDatabase::Initialize()
c801d85f 263{
c50f92d0
VZ
264 if ( m_map )
265 {
266 // already initialized
267 return;
268 }
269
270 m_map = new wxStringToColourHashMap;
271
f6bcfd97
BP
272 static const struct wxColourDesc
273 {
274 const wxChar *name;
5c519b6c 275 unsigned char r,g,b;
f6bcfd97
BP
276 }
277 wxColourTable[] =
278 {
5e2ab1ea 279 {wxT("AQUAMARINE"),112, 219, 147},
f6bcfd97
BP
280 {wxT("BLACK"),0, 0, 0},
281 {wxT("BLUE"), 0, 0, 255},
5e2ab1ea 282 {wxT("BLUE VIOLET"), 159, 95, 159},
f6bcfd97 283 {wxT("BROWN"), 165, 42, 42},
5e2ab1ea
VZ
284 {wxT("CADET BLUE"), 95, 159, 159},
285 {wxT("CORAL"), 255, 127, 0},
286 {wxT("CORNFLOWER BLUE"), 66, 66, 111},
f6bcfd97 287 {wxT("CYAN"), 0, 255, 255},
5e2ab1ea
VZ
288 {wxT("DARK GREY"), 47, 47, 47}, // ?
289
290 {wxT("DARK GREEN"), 47, 79, 47},
291 {wxT("DARK OLIVE GREEN"), 79, 79, 47},
f6bcfd97 292 {wxT("DARK ORCHID"), 153, 50, 204},
5e2ab1ea 293 {wxT("DARK SLATE BLUE"), 107, 35, 142},
f6bcfd97 294 {wxT("DARK SLATE GREY"), 47, 79, 79},
5e2ab1ea
VZ
295 {wxT("DARK TURQUOISE"), 112, 147, 219},
296 {wxT("DIM GREY"), 84, 84, 84},
297 {wxT("FIREBRICK"), 142, 35, 35},
298 {wxT("FOREST GREEN"), 35, 142, 35},
299 {wxT("GOLD"), 204, 127, 50},
300 {wxT("GOLDENROD"), 219, 219, 112},
301 {wxT("GREY"), 128, 128, 128},
f6bcfd97 302 {wxT("GREEN"), 0, 255, 0},
5e2ab1ea
VZ
303 {wxT("GREEN YELLOW"), 147, 219, 112},
304 {wxT("INDIAN RED"), 79, 47, 47},
305 {wxT("KHAKI"), 159, 159, 95},
306 {wxT("LIGHT BLUE"), 191, 216, 216},
307 {wxT("LIGHT GREY"), 192, 192, 192},
308 {wxT("LIGHT STEEL BLUE"), 143, 143, 188},
309 {wxT("LIME GREEN"), 50, 204, 50},
310 {wxT("LIGHT MAGENTA"), 255, 0, 255},
f6bcfd97 311 {wxT("MAGENTA"), 255, 0, 255},
5e2ab1ea
VZ
312 {wxT("MAROON"), 142, 35, 107},
313 {wxT("MEDIUM AQUAMARINE"), 50, 204, 153},
314 {wxT("MEDIUM GREY"), 100, 100, 100},
315 {wxT("MEDIUM BLUE"), 50, 50, 204},
316 {wxT("MEDIUM FOREST GREEN"), 107, 142, 35},
317 {wxT("MEDIUM GOLDENROD"), 234, 234, 173},
318 {wxT("MEDIUM ORCHID"), 147, 112, 219},
319 {wxT("MEDIUM SEA GREEN"), 66, 111, 66},
320 {wxT("MEDIUM SLATE BLUE"), 127, 0, 255},
321 {wxT("MEDIUM SPRING GREEN"), 127, 255, 0},
322 {wxT("MEDIUM TURQUOISE"), 112, 219, 219},
323 {wxT("MEDIUM VIOLET RED"), 219, 112, 147},
324 {wxT("MIDNIGHT BLUE"), 47, 47, 79},
325 {wxT("NAVY"), 35, 35, 142},
326 {wxT("ORANGE"), 204, 50, 50},
327 {wxT("ORANGE RED"), 255, 0, 127},
328 {wxT("ORCHID"), 219, 112, 219},
329 {wxT("PALE GREEN"), 143, 188, 143},
330 {wxT("PINK"), 188, 143, 234},
331 {wxT("PLUM"), 234, 173, 234},
332 {wxT("PURPLE"), 176, 0, 255},
f6bcfd97 333 {wxT("RED"), 255, 0, 0},
5e2ab1ea
VZ
334 {wxT("SALMON"), 111, 66, 66},
335 {wxT("SEA GREEN"), 35, 142, 107},
336 {wxT("SIENNA"), 142, 107, 35},
337 {wxT("SKY BLUE"), 50, 153, 204},
338 {wxT("SLATE BLUE"), 0, 127, 255},
f6bcfd97 339 {wxT("SPRING GREEN"), 0, 255, 127},
5e2ab1ea
VZ
340 {wxT("STEEL BLUE"), 35, 107, 142},
341 {wxT("TAN"), 219, 147, 112},
f6bcfd97 342 {wxT("THISTLE"), 216, 191, 216},
5e2ab1ea
VZ
343 {wxT("TURQUOISE"), 173, 234, 234},
344 {wxT("VIOLET"), 79, 47, 79},
345 {wxT("VIOLET RED"), 204, 50, 153},
346 {wxT("WHEAT"), 216, 216, 191},
f6bcfd97
BP
347 {wxT("WHITE"), 255, 255, 255},
348 {wxT("YELLOW"), 255, 255, 0},
aad6765c 349 {wxT("YELLOW GREEN"), 153, 204, 50}
f6bcfd97
BP
350 };
351
c50f92d0 352 size_t n;
bf2c4b94
DW
353
354 for ( n = 0; n < WXSIZEOF(wxColourTable); n++ )
f6bcfd97
BP
355 {
356 const wxColourDesc& cc = wxColourTable[n];
c50f92d0 357 (*m_map)[cc.name] = new wxColour(cc.r, cc.g, cc.b);
f6bcfd97 358 }
c50f92d0 359
19bf0c69
DW
360#ifdef __WXPM__
361 m_palTable = new long[n];
362 for ( n = 0; n < WXSIZEOF(wxColourTable); n++ )
363 {
364 const wxColourDesc& cc = wxColourTable[n];
365 m_palTable[n] = OS2RGB(cc.r,cc.g,cc.b);
366 }
367 m_nSize = n;
368#endif
c801d85f
KB
369}
370
c50f92d0
VZ
371// ----------------------------------------------------------------------------
372// wxColourDatabase operations
373// ----------------------------------------------------------------------------
222ed1d6 374
c50f92d0 375void wxColourDatabase::AddColour(const wxString& name, const wxColour& colour)
222ed1d6 376{
c50f92d0 377 Initialize();
222ed1d6 378
c50f92d0
VZ
379 // canonicalize the colour names before using them as keys: they should be
380 // in upper case
8f520a56
MB
381 wxString colName = name;
382 colName.MakeUpper();
c50f92d0
VZ
383
384 // ... and we also allow both grey/gray
385 wxString colNameAlt = colName;
386 if ( !colNameAlt.Replace(_T("GRAY"), _T("GREY")) )
387 {
388 // but in this case it is not necessary so avoid extra search below
389 colNameAlt.clear();
390 }
8f520a56
MB
391
392 wxStringToColourHashMap::iterator it = m_map->find(colName);
c50f92d0
VZ
393 if ( it == m_map->end() && !colNameAlt.empty() )
394 it = m_map->find(colNameAlt);
8f520a56
MB
395 if ( it != m_map->end() )
396 {
c50f92d0
VZ
397 *(it->second) = colour;
398 }
399 else // new colour
400 {
5767e836 401 (*m_map)[colName] = new wxColour(colour);
8f520a56 402 }
8f520a56
MB
403}
404
c50f92d0 405wxColour wxColourDatabase::Find(const wxString& colour) const
c801d85f 406{
c50f92d0
VZ
407 wxColourDatabase * const self = wxConstCast(this, wxColourDatabase);
408 self->Initialize();
409
c50f92d0 410 // make the comparaison case insensitive and also match both grey and gray
f6bcfd97
BP
411 wxString colName = colour;
412 colName.MakeUpper();
c50f92d0
VZ
413 wxString colNameAlt = colName;
414 if ( !colNameAlt.Replace(_T("GRAY"), _T("GREY")) )
415 colNameAlt.clear();
f6bcfd97 416
222ed1d6 417 wxStringToColourHashMap::iterator it = m_map->find(colName);
c50f92d0
VZ
418 if ( it == m_map->end() && !colNameAlt.empty() )
419 it = m_map->find(colNameAlt);
222ed1d6 420 if ( it != m_map->end() )
c50f92d0 421 return *(it->second);
34138703 422
40989e46
WS
423 // we did not find any result in existing colours:
424 // we won't use wxString -> wxColour conversion because the
425 // wxColour::Set(const wxString &) function which does that conversion
426 // internally uses this function (wxColourDatabase::Find) and we want
427 // to avoid infinite recursion !
c50f92d0 428 return wxNullColour;
c801d85f
KB
429}
430
c50f92d0 431wxString wxColourDatabase::FindName(const wxColour& colour) const
c801d85f 432{
c50f92d0
VZ
433 wxColourDatabase * const self = wxConstCast(this, wxColourDatabase);
434 self->Initialize();
8bbe427f 435
222ed1d6
MB
436 typedef wxStringToColourHashMap::iterator iterator;
437
c50f92d0 438 for ( iterator it = m_map->begin(), en = m_map->end(); it != en; ++it )
a23fd0e1 439 {
c50f92d0 440 if ( *(it->second) == colour )
222ed1d6 441 return it->first;
a23fd0e1 442 }
c801d85f 443
222ed1d6 444 return wxEmptyString;
c801d85f
KB
445}
446
c50f92d0
VZ
447// ----------------------------------------------------------------------------
448// deprecated wxColourDatabase methods
449// ----------------------------------------------------------------------------
450
ca3e85cf 451#if WXWIN_COMPATIBILITY_2_6
c50f92d0
VZ
452wxColour *wxColourDatabase::FindColour(const wxString& name)
453{
98de2b68
DS
454 // This function is deprecated, use Find() instead.
455 // Formerly this function sometimes would return a deletable pointer and
456 // sometimes a non-deletable one (when returning a colour from the database).
457 // Trying to delete the latter anyway results in problems, so probably
458 // nobody ever freed the pointers. Currently it always returns a new
459 // instance, which means there will be memory leaks.
460 wxLogDebug(wxT("wxColourDataBase::FindColour():")
461 wxT(" Please use wxColourDataBase::Find() instead"));
462
492e2a5b
VZ
463 // using a static variable here is not the most elegant solution but unless
464 // we want to make wxStringToColourHashMap public (i.e. move it to the
465 // header) so that we could have a member function returning
466 // wxStringToColourHashMap::iterator, there is really no good way to do it
467 // otherwise
468 //
469 // and knowing that this function is going to disappear in the next release
470 // anyhow I don't want to waste time on this
98de2b68 471
492e2a5b
VZ
472 static wxColour s_col;
473
474 s_col = Find(name);
475 if ( !s_col.Ok() )
c50f92d0
VZ
476 return NULL;
477
98de2b68 478 return new wxColour(s_col);
c50f92d0 479}
ca3e85cf 480#endif // WXWIN_COMPATIBILITY_2_6
c50f92d0
VZ
481
482// ============================================================================
483// stock objects
484// ============================================================================
485
f516d986
VZ
486static wxStockGDI gs_wxStockGDI_instance;
487wxStockGDI* wxStockGDI::ms_instance = &gs_wxStockGDI_instance;
488wxObject* wxStockGDI::ms_stockObject[ITEMCOUNT];
489
490wxStockGDI::wxStockGDI()
7ecb8b06 491{
f516d986 492}
1c193821 493
f516d986
VZ
494wxStockGDI::~wxStockGDI()
495{
a3622daa 496}
c801d85f 497
f516d986 498void wxStockGDI::DeleteAll()
a3622daa 499{
f516d986
VZ
500 for (unsigned i = 0; i < ITEMCOUNT; i++)
501 {
502 delete ms_stockObject[i];
503 ms_stockObject[i] = NULL;
504 }
505}
c801d85f 506
f516d986
VZ
507const wxBrush* wxStockGDI::GetBrush(Item item)
508{
509 wxBrush* brush = wx_static_cast(wxBrush*, ms_stockObject[item]);
510 if (brush == NULL)
511 {
512 switch (item)
513 {
514 case BRUSH_BLACK:
515 brush = new wxBrush(*GetColour(COLOUR_BLACK), wxSOLID);
516 break;
517 case BRUSH_BLUE:
518 brush = new wxBrush(*GetColour(COLOUR_BLUE), wxSOLID);
519 break;
520 case BRUSH_CYAN:
521 brush = new wxBrush(*GetColour(COLOUR_CYAN), wxSOLID);
522 break;
523 case BRUSH_GREEN:
524 brush = new wxBrush(*GetColour(COLOUR_GREEN), wxSOLID);
525 break;
526 case BRUSH_GREY:
527 brush = new wxBrush(wxColour(wxT("GREY")), wxSOLID);
528 break;
529 case BRUSH_LIGHTGREY:
530 brush = new wxBrush(*GetColour(COLOUR_LIGHTGREY), wxSOLID);
531 break;
532 case BRUSH_MEDIUMGREY:
533 brush = new wxBrush(wxColour(wxT("MEDIUM GREY")), wxSOLID);
534 break;
535 case BRUSH_RED:
536 brush = new wxBrush(*GetColour(COLOUR_RED), wxSOLID);
537 break;
538 case BRUSH_TRANSPARENT:
539 brush = new wxBrush(*GetColour(COLOUR_BLACK), wxTRANSPARENT);
540 break;
541 case BRUSH_WHITE:
542 brush = new wxBrush(*GetColour(COLOUR_WHITE), wxSOLID);
543 break;
544 default:
545 wxFAIL;
546 }
547 ms_stockObject[item] = brush;
548 }
549 return brush;
550}
696e1ea0 551
f516d986
VZ
552const wxColour* wxStockGDI::GetColour(Item item)
553{
554 wxColour* colour = wx_static_cast(wxColour*, ms_stockObject[item]);
555 if (colour == NULL)
556 {
557 switch (item)
558 {
559 case COLOUR_BLACK:
560 colour = new wxColour(0, 0, 0);
561 break;
562 case COLOUR_BLUE:
563 colour = new wxColour(0, 0, 255);
564 break;
565 case COLOUR_CYAN:
566 colour = new wxColour(wxT("CYAN"));
567 break;
568 case COLOUR_GREEN:
569 colour = new wxColour(0, 255, 0);
570 break;
571 case COLOUR_LIGHTGREY:
572 colour = new wxColour(wxT("LIGHT GREY"));
573 break;
574 case COLOUR_RED:
575 colour = new wxColour(255, 0, 0);
576 break;
577 case COLOUR_WHITE:
578 colour = new wxColour(255, 255, 255);
579 break;
580 default:
581 wxFAIL;
582 }
583 ms_stockObject[item] = colour;
584 }
585 return colour;
586}
587
588const wxCursor* wxStockGDI::GetCursor(Item item)
589{
590 wxCursor* cursor = wx_static_cast(wxCursor*, ms_stockObject[item]);
591 if (cursor == NULL)
592 {
593 switch (item)
594 {
595 case CURSOR_CROSS:
596 cursor = new wxCursor(wxCURSOR_CROSS);
597 break;
598 case CURSOR_HOURGLASS:
599 cursor = new wxCursor(wxCURSOR_WAIT);
600 break;
601 case CURSOR_STANDARD:
602 cursor = new wxCursor(wxCURSOR_ARROW);
603 break;
604 default:
605 wxFAIL;
606 }
607 ms_stockObject[item] = cursor;
608 }
609 return cursor;
610}
611
612const wxFont* wxStockGDI::GetFont(Item item)
613{
614 wxFont* font = wx_static_cast(wxFont*, ms_stockObject[item]);
615 if (font == NULL)
616 {
617 switch (item)
618 {
619 case FONT_ITALIC:
620 font = new wxFont(GetFont(FONT_NORMAL)->GetPointSize(), wxROMAN, wxITALIC, wxNORMAL);
621 break;
622 case FONT_NORMAL:
623 font = new wxFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
624 break;
625 case FONT_SMALL:
626 font = new wxFont(GetFont(FONT_NORMAL)->GetPointSize() - 2, wxSWISS, wxNORMAL, wxNORMAL);
627 break;
628 case FONT_SWISS:
629 font = new wxFont(GetFont(FONT_NORMAL)->GetPointSize(), wxSWISS, wxNORMAL, wxNORMAL);
630 break;
631 default:
632 wxFAIL;
633 }
634 ms_stockObject[item] = font;
635 }
636 return font;
637}
c801d85f 638
f516d986
VZ
639const wxPen* wxStockGDI::GetPen(Item item)
640{
641 wxPen* pen = wx_static_cast(wxPen*, ms_stockObject[item]);
642 if (pen == NULL)
643 {
644 switch (item)
645 {
646 case PEN_BLACK:
647 pen = new wxPen(*GetColour(COLOUR_BLACK), 1, wxSOLID);
648 break;
649 case PEN_BLACKDASHED:
650 pen = new wxPen(*GetColour(COLOUR_BLACK), 1, wxSHORT_DASH);
651 break;
652 case PEN_CYAN:
653 pen = new wxPen(*GetColour(COLOUR_CYAN), 1, wxSOLID);
654 break;
655 case PEN_GREEN:
656 pen = new wxPen(*GetColour(COLOUR_GREEN), 1, wxSOLID);
657 break;
658 case PEN_GREY:
659 pen = new wxPen(wxColour(wxT("GREY")), 1, wxSOLID);
660 break;
661 case PEN_LIGHTGREY:
662 pen = new wxPen(*GetColour(COLOUR_LIGHTGREY), 1, wxSOLID);
663 break;
664 case PEN_MEDIUMGREY:
665 pen = new wxPen(wxColour(wxT("MEDIUM GREY")), 1, wxSOLID);
666 break;
667 case PEN_RED:
668 pen = new wxPen(*GetColour(COLOUR_RED), 1, wxSOLID);
669 break;
670 case PEN_TRANSPARENT:
671 pen = new wxPen(*GetColour(COLOUR_BLACK), 1, wxTRANSPARENT);
672 break;
673 case PEN_WHITE:
674 pen = new wxPen(*GetColour(COLOUR_WHITE), 1, wxSOLID);
675 break;
676 default:
677 wxFAIL;
678 }
679 ms_stockObject[item] = pen;
680 }
681 return pen;
c801d85f
KB
682}
683
f516d986 684void wxInitializeStockLists()
c801d85f 685{
f516d986
VZ
686 wxTheColourDatabase = new wxColourDatabase;
687
688 wxTheBrushList = new wxBrushList;
689 wxThePenList = new wxPenList;
690 wxTheFontList = new wxFontList;
a3622daa
VZ
691}
692
7ecb8b06
VZ
693void wxDeleteStockLists()
694{
5d3e7b52
WS
695 wxDELETE(wxTheBrushList);
696 wxDELETE(wxThePenList);
697 wxDELETE(wxTheFontList);
c801d85f
KB
698}
699
7ecb8b06
VZ
700// ============================================================================
701// wxTheXXXList stuff (semi-obsolete)
702// ============================================================================
703
1de8d512 704wxGDIObjListBase::wxGDIObjListBase()
c801d85f 705{
c801d85f
KB
706}
707
1de8d512 708wxGDIObjListBase::~wxGDIObjListBase()
c801d85f 709{
1de8d512 710 for (wxList::compatibility_iterator node = list.GetFirst(); node; node = node->GetNext())
c801d85f 711 {
1de8d512 712 delete wx_static_cast(wxObject*, node->GetData());
c801d85f
KB
713 }
714}
715
debe6624 716wxPen *wxPenList::FindOrCreatePen (const wxColour& colour, int width, int style)
c801d85f 717{
1de8d512 718 for (wxList::compatibility_iterator node = list.GetFirst(); node; node = node->GetNext())
13b6e335 719 {
b1d4dd7a 720 wxPen *each_pen = (wxPen *) node->GetData ();
1de8d512 721 if (
13b6e335
VZ
722 each_pen->GetWidth () == width &&
723 each_pen->GetStyle () == style &&
724 each_pen->GetColour ().Red () == colour.Red () &&
725 each_pen->GetColour ().Green () == colour.Green () &&
726 each_pen->GetColour ().Blue () == colour.Blue ())
727 return each_pen;
728 }
729
1de8d512
VZ
730 wxPen* pen = NULL;
731 wxPen penTmp(colour, width, style);
732 if (penTmp.Ok())
c801d85f 733 {
1de8d512
VZ
734 pen = new wxPen(penTmp);
735 list.Append(pen);
c801d85f 736 }
c801d85f 737
13b6e335 738 return pen;
c801d85f
KB
739}
740
debe6624 741wxBrush *wxBrushList::FindOrCreateBrush (const wxColour& colour, int style)
c801d85f 742{
1de8d512 743 for (wxList::compatibility_iterator node = list.GetFirst(); node; node = node->GetNext())
c801d85f 744 {
b1d4dd7a 745 wxBrush *each_brush = (wxBrush *) node->GetData ();
1de8d512 746 if (
13b6e335
VZ
747 each_brush->GetStyle () == style &&
748 each_brush->GetColour ().Red () == colour.Red () &&
749 each_brush->GetColour ().Green () == colour.Green () &&
750 each_brush->GetColour ().Blue () == colour.Blue ())
751 return each_brush;
c801d85f 752 }
6d167489 753
1de8d512
VZ
754 wxBrush* brush = NULL;
755 wxBrush brushTmp(colour, style);
756 if (brushTmp.Ok())
13b6e335 757 {
1de8d512
VZ
758 brush = new wxBrush(brushTmp);
759 list.Append(brush);
13b6e335 760 }
6d167489 761
13b6e335 762 return brush;
c801d85f
KB
763}
764
f6bcfd97
BP
765wxFont *wxFontList::FindOrCreateFont(int pointSize,
766 int family,
767 int style,
768 int weight,
769 bool underline,
770 const wxString& facename,
771 wxFontEncoding encoding)
c801d85f 772{
1de8d512 773 wxFont *font;
222ed1d6 774 wxList::compatibility_iterator node;
1de8d512 775 for (node = list.GetFirst(); node; node = node->GetNext())
c801d85f 776 {
b1d4dd7a 777 font = (wxFont *)node->GetData();
1de8d512 778 if (
f6bcfd97
BP
779 font->GetPointSize () == pointSize &&
780 font->GetStyle () == style &&
781 font->GetWeight () == weight &&
782 font->GetUnderlined () == underline )
783 {
784 int fontFamily = font->GetFamily();
785
619d0528 786#if defined(__WXGTK__)
f6bcfd97
BP
787 // under GTK the default family is wxSWISS, so looking for a font
788 // with wxDEFAULT family should return a wxSWISS one instead of
789 // creating a new one
790 bool same = (fontFamily == family) ||
791 (fontFamily == wxSWISS && family == wxDEFAULT);
792#else // !GTK
793 // VZ: but why elsewhere do we require an exact match? mystery...
794 bool same = fontFamily == family;
795#endif // GTK/!GTK
796
797 // empty facename matches anything at all: this is bad because
798 // depending on which fonts are already created, we might get back
799 // a different font if we create it with empty facename, but it is
800 // still better than never matching anything in the cache at all
801 // in this case
8d8fbb9d 802 if ( same && !facename.empty() )
f6bcfd97
BP
803 {
804 const wxString& fontFace = font->GetFaceName();
805
806 // empty facename matches everything
807 same = !fontFace || fontFace == facename;
808 }
809
810 if ( same && (encoding != wxFONTENCODING_DEFAULT) )
811 {
812 // have to match the encoding too
813 same = font->GetEncoding() == encoding;
814 }
815
816 if ( same )
817 {
818 return font;
819 }
820 }
c801d85f 821 }
6d167489 822
1de8d512
VZ
823 // font not found, create the new one
824 font = NULL;
825 wxFont fontTmp(pointSize, family, style, weight, underline, facename, encoding);
826 if (fontTmp.Ok())
f6bcfd97 827 {
1de8d512
VZ
828 font = new wxFont(fontTmp);
829 list.Append(font);
f6bcfd97 830 }
6d167489 831
f6bcfd97 832 return font;
c801d85f
KB
833}
834
1de8d512
VZ
835#if WXWIN_COMPATIBILITY_2_6
836void wxBrushList::AddBrush(wxBrush*) { }
837void wxBrushList::RemoveBrush(wxBrush*) { }
838void wxFontList::AddFont(wxFont*) { }
839void wxFontList::RemoveFont(wxFont*) { }
840void wxPenList::AddPen(wxPen*) { }
841void wxPenList::RemovePen(wxPen*) { }
842#endif
c801d85f 843
6a6c0a8b
JS
844wxSize wxGetDisplaySize()
845{
846 int x, y;
847 wxDisplaySize(& x, & y);
848 return wxSize(x, y);
849}
850
ec5d7799
RD
851wxRect wxGetClientDisplayRect()
852{
853 int x, y, width, height;
854 wxClientDisplayRect(&x, &y, &width, &height); // call plat-specific version
855 return wxRect(x, y, width, height);
856}
857
904a68b6
RL
858wxSize wxGetDisplaySizeMM()
859{
860 int x, y;
861 wxDisplaySizeMM(& x, & y);
862 return wxSize(x, y);
863}
864
8bbe427f
VZ
865wxResourceCache::~wxResourceCache ()
866{
222ed1d6 867 wxList::compatibility_iterator node = GetFirst ();
f6bcfd97 868 while (node) {
b1d4dd7a 869 wxObject *item = (wxObject *)node->GetData();
f6bcfd97 870 delete item;
a3622daa 871
b1d4dd7a 872 node = node->GetNext ();
a3622daa 873 }
a3622daa 874}