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