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