]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/font.cpp
Added #include to get FIONBIO on Solaris 2.6
[wxWidgets.git] / src / gtk / font.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: font.cpp
3// Purpose:
4// Author: Robert Roebling
5// Created: 01/02/97
6// Id:
7// Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11#ifdef __GNUG__
12#pragma implementation "font.h"
13#endif
14
15#include "wx/font.h"
16#include "wx/utils.h"
17#include <strings.h>
18
19//-----------------------------------------------------------------------------
20// local data
21//-----------------------------------------------------------------------------
22
a3622daa 23extern wxFontNameDirectory *wxTheFontNameDirectory;
c801d85f
KB
24
25//-----------------------------------------------------------------------------
26// wxFont
27//-----------------------------------------------------------------------------
28
29class wxFontRefData: public wxObjectRefData
30{
31 public:
32
33 wxFontRefData(void);
34 ~wxFontRefData(void);
35
36 wxList m_scaled_xfonts;
37 int m_pointSize;
38 int m_family, m_style, m_weight;
39 bool m_underlined;
40 int m_fontId;
41 char* m_faceName;
42
43 bool m_byXFontName;
44 GdkFont *m_font;
45
46 friend wxFont;
47};
48
49wxFontRefData::wxFontRefData(void) : m_scaled_xfonts(wxKEY_INTEGER)
50{
51 m_byXFontName = FALSE;
d84eb083
RR
52 m_pointSize = 12;
53 m_family = wxSWISS;
54 m_style = wxNORMAL;
55 m_weight = wxNORMAL;
c801d85f
KB
56 m_underlined = FALSE;
57 m_fontId = 0;
c67daf87
UR
58 m_faceName = (char *) NULL;
59 m_font = (GdkFont *) NULL;
ff7b1510 60}
c801d85f
KB
61
62wxFontRefData::~wxFontRefData(void)
63{
64 wxNode *node = m_scaled_xfonts.First();
65 while (node)
66 {
67 GdkFont *font = (GdkFont*)node->Data();
68 wxNode *next = node->Next();
69 gdk_font_unref( font );
70 node = next;
ff7b1510 71 }
c801d85f
KB
72 if (m_faceName)
73 {
74 delete m_faceName;
c67daf87 75 m_faceName = (char *) NULL;
ff7b1510 76 }
c801d85f 77 if (m_font) gdk_font_unref( m_font );
ff7b1510 78}
c801d85f
KB
79
80//-----------------------------------------------------------------------------
81
82#define M_FONTDATA ((wxFontRefData *)m_refData)
83
84IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
85
86wxFont::wxFont(void)
87{
88 if (wxTheFontList) wxTheFontList->Append( this );
ff7b1510 89}
c801d85f
KB
90
91wxFont::wxFont( char *xFontName )
92{
93 if (!xFontName) return;
94
95 m_refData = new wxFontRefData();
96
97 M_FONTDATA->m_byXFontName = TRUE;
98 M_FONTDATA->m_font = gdk_font_load( xFontName );
ff7b1510 99}
c801d85f
KB
100
101wxFont::wxFont(int PointSize, int FontIdOrFamily, int Style, int Weight,
102 bool Underlined, const char* Face)
103{
104 m_refData = new wxFontRefData();
105
106 if ((M_FONTDATA->m_faceName = (Face) ? copystring(Face) : (char*)NULL) )
107 {
a3622daa
VZ
108 M_FONTDATA->m_fontId = wxTheFontNameDirectory->FindOrCreateFontId( Face, FontIdOrFamily );
109 M_FONTDATA->m_family = wxTheFontNameDirectory->GetFamily( FontIdOrFamily );
c801d85f
KB
110 }
111 else
112 {
113 M_FONTDATA->m_fontId = FontIdOrFamily;
a3622daa 114 M_FONTDATA->m_family = wxTheFontNameDirectory->GetFamily( FontIdOrFamily );
ff7b1510 115 }
d84eb083 116 if (Style == wxDEFAULT) Style = wxSWISS;
c801d85f 117 M_FONTDATA->m_style = Style;
d84eb083 118 if (Weight == wxDEFAULT) Weight = wxNORMAL;
c801d85f 119 M_FONTDATA->m_weight = Weight;
d84eb083 120 if (PointSize == wxDEFAULT) PointSize = 10;
c801d85f
KB
121 M_FONTDATA->m_pointSize = PointSize;
122 M_FONTDATA->m_underlined = Underlined;
123
124 if (wxTheFontList) wxTheFontList->Append( this );
ff7b1510 125}
c801d85f
KB
126
127wxFont::wxFont(int PointSize, const char *Face, int Family, int Style,
128 int Weight, bool Underlined)
129{
130 m_refData = new wxFontRefData();
131
a3622daa 132 M_FONTDATA->m_fontId = wxTheFontNameDirectory->FindOrCreateFontId( Face, Family );
c801d85f 133 M_FONTDATA->m_faceName = (Face) ? copystring(Face) : (char*)NULL;
a3622daa 134 M_FONTDATA->m_family = wxTheFontNameDirectory->GetFamily( M_FONTDATA->m_fontId );
c801d85f
KB
135 M_FONTDATA->m_style = Style;
136 M_FONTDATA->m_weight = Weight;
137 M_FONTDATA->m_pointSize = PointSize;
138 M_FONTDATA->m_underlined = Underlined;
139
140 if (wxTheFontList) wxTheFontList->Append( this );
ff7b1510 141}
c801d85f
KB
142
143wxFont::wxFont( const wxFont& font )
144{
145 Ref( font );
52cbfcf0
RR
146
147 if (wxTheFontList) wxTheFontList->Append( this );
ff7b1510 148}
c801d85f
KB
149
150wxFont::wxFont( const wxFont* font )
151{
152 UnRef();
153 if (font) Ref( *font );
52cbfcf0
RR
154
155 if (wxTheFontList) wxTheFontList->Append( this );
ff7b1510 156}
c801d85f
KB
157
158wxFont::~wxFont(void)
159{
160 if (wxTheFontList) wxTheFontList->DeleteObject( this );
ff7b1510 161}
c801d85f
KB
162
163wxFont& wxFont::operator = ( const wxFont& font )
164{
165 if (*this == font) return (*this);
166 Ref( font );
167 return *this;
ff7b1510 168}
c801d85f
KB
169
170bool wxFont::operator == ( const wxFont& font )
171{
172 return m_refData == font.m_refData;
ff7b1510 173}
c801d85f
KB
174
175bool wxFont::operator != ( const wxFont& font )
176{
177 return m_refData != font.m_refData;
ff7b1510 178}
c801d85f 179
d84eb083 180bool wxFont::Ok() const
c801d85f 181{
d84eb083
RR
182 if (!m_refData)
183 {
184 wxFAIL_MSG( "invalid font" );
185 return FALSE;
186 }
187 else
188 return TRUE;
ff7b1510 189}
c801d85f
KB
190
191int wxFont::GetPointSize(void) const
192{
d84eb083
RR
193 if (!Ok()) return 0;
194
c801d85f 195 return M_FONTDATA->m_pointSize;
ff7b1510 196}
c801d85f
KB
197
198wxString wxFont::GetFaceString(void) const
199{
d84eb083
RR
200 if (!Ok()) return "";
201
a3622daa 202 wxString s = wxTheFontNameDirectory->GetFontName( M_FONTDATA->m_fontId );
c801d85f 203 return s;
ff7b1510 204}
c801d85f
KB
205
206wxString wxFont::GetFaceName(void) const
207{
d84eb083
RR
208 if (!Ok()) return "";
209
a3622daa 210 wxString s = wxTheFontNameDirectory->GetFontName( M_FONTDATA->m_fontId );
c801d85f 211 return s;
ff7b1510 212}
c801d85f
KB
213
214int wxFont::GetFamily(void) const
215{
d84eb083
RR
216 if (!Ok()) return 0;
217
c801d85f 218 return M_FONTDATA->m_family;
ff7b1510 219}
c801d85f
KB
220
221wxString wxFont::GetFamilyString(void) const
222{
d84eb083
RR
223 if (!Ok()) return "wxDEFAULT";
224
225 switch (M_FONTDATA->m_family)
226 {
227 case wxDECORATIVE: return wxString("wxDECORATIVE");
228 case wxROMAN: return wxString("wxROMAN");
229 case wxSCRIPT: return wxString("wxSCRIPT");
230 case wxSWISS: return wxString("wxSWISS");
231 case wxMODERN: return wxString("wxMODERN");
232 case wxTELETYPE: return wxString("wxTELETYPE");
233 default: return "wxDEFAULT";
234 }
235
236 return "wxDEFAULT";
ff7b1510 237}
c801d85f
KB
238
239int wxFont::GetFontId(void) const
240{
d84eb083
RR
241 if (!Ok()) return 0;
242
c801d85f 243 return M_FONTDATA->m_fontId; // stub
ff7b1510 244}
c801d85f
KB
245
246int wxFont::GetStyle(void) const
247{
d84eb083
RR
248 if (!Ok()) return 0;
249
c801d85f 250 return M_FONTDATA->m_style;
ff7b1510 251}
c801d85f
KB
252
253wxString wxFont::GetStyleString(void) const
254{
d84eb083
RR
255 if (!Ok()) return "wxDEFAULT";
256
257 switch (M_FONTDATA->m_style)
258 {
259 case wxNORMAL: return wxString("wxNORMAL");
260 case wxSLANT: return wxString("wxSLANT");
261 case wxITALIC: return wxString("wxITALIC");
262 default: return wxString("wxDEFAULT");
263 }
264
265 return wxString("wxDEFAULT");
ff7b1510 266}
c801d85f
KB
267
268int wxFont::GetWeight(void) const
269{
d84eb083
RR
270 if (!Ok()) return 0;
271
c801d85f 272 return M_FONTDATA->m_weight;
ff7b1510 273}
c801d85f
KB
274
275wxString wxFont::GetWeightString(void) const
276{
d84eb083
RR
277 if (!Ok()) return "wxDEFAULT";
278
279 switch (M_FONTDATA->m_weight)
280 {
281 case wxNORMAL: return wxString("wxNORMAL");
282 case wxBOLD: return wxString("wxBOLD");
283 case wxLIGHT: return wxString("wxLIGHT");
284 default: return wxString("wxDEFAULT");
285 }
286
287 return wxString("wxDEFAULT");
ff7b1510 288}
c801d85f
KB
289
290bool wxFont::GetUnderlined(void) const
291{
d84eb083
RR
292 if (!Ok()) return FALSE;
293
c801d85f 294 return M_FONTDATA->m_underlined;
ff7b1510 295}
c801d85f
KB
296
297//-----------------------------------------------------------------------------
298// get internal representation of font
299//-----------------------------------------------------------------------------
300
301// local help function
302static GdkFont *wxLoadQueryNearestFont(int point_size, int fontid,
303 int style, int weight,
304 bool underlined);
305
c33c4050 306GdkFont *wxFont::GetInternalFont(float scale) const
c801d85f
KB
307{
308 if (M_FONTDATA->m_byXFontName) return M_FONTDATA->m_font;
309
310 long int_scale = long(scale * 100.0 + 0.5); // key for fontlist
311 int point_scale = (M_FONTDATA->m_pointSize * 10 * int_scale) / 100;
c67daf87 312 GdkFont *font = (GdkFont *) NULL;
c801d85f
KB
313
314 wxNode *node = M_FONTDATA->m_scaled_xfonts.Find(int_scale);
315 if (node)
316 {
317 font = (GdkFont*)node->Data();
318 }
319 else
320 {
321 font = wxLoadQueryNearestFont( point_scale, M_FONTDATA->m_fontId, M_FONTDATA->m_style,
322 M_FONTDATA->m_weight, M_FONTDATA->m_underlined );
323 M_FONTDATA->m_scaled_xfonts.Append( int_scale, (wxObject*)font );
ff7b1510 324 }
c801d85f
KB
325 if (!font)
326 printf("could not load any font");
327// wxError("could not load any font", "wxFont");
328 return font;
ff7b1510 329}
c801d85f
KB
330
331//-----------------------------------------------------------------------------
332// local utilities to find a X font
333//-----------------------------------------------------------------------------
334
335static GdkFont *wxLoadQueryFont(int point_size, int fontid, int style,
336 int weight, bool WXUNUSED(underlined))
337{
338 char buffer[512];
a3622daa 339 char *name = wxTheFontNameDirectory->GetScreenName( fontid, weight, style );
c801d85f
KB
340
341 if (!name)
342 name = "-*-*-*-*-*-*-*-%d-*-*-*-*-*-*";
343 sprintf(buffer, name, point_size);
344
345 return gdk_font_load( buffer );
346}
347
348static GdkFont *wxLoadQueryNearestFont(int point_size, int fontid,
349 int style, int weight,
350 bool underlined)
351{
352 GdkFont *font;
353
354 font = wxLoadQueryFont( point_size, fontid, style, weight, underlined );
355
356 if (!font) {
357 // search up and down by stepsize 10
358 int max_size = point_size + 20 * (1 + (point_size/180));
359 int min_size = point_size - 20 * (1 + (point_size/180));
360 int i;
361
362 // Search for smaller size (approx.)
363 for (i=point_size-10; !font && i >= 10 && i >= min_size; i -= 10)
364 font = wxLoadQueryFont(i, fontid, style, weight, underlined);
365 // Search for larger size (approx.)
366 for (i=point_size+10; !font && i <= max_size; i += 10)
367 font = wxLoadQueryFont(i, fontid, style, weight, underlined);
368 // Try default family
369 if (!font && fontid != wxDEFAULT)
370 font = wxLoadQueryFont(point_size, wxDEFAULT, style,
371 weight, underlined);
372 // Bogus font
373 if (!font)
374 font = wxLoadQueryFont(120, wxDEFAULT, wxNORMAL, wxNORMAL,
375 underlined);
376 }
377 return font;
378}
379
380//-----------------------------------------------------------------------------
381// face names and index functions
382//-----------------------------------------------------------------------------
383
384static char *font_defaults[] = {
385 "FamilyDefault", "Default",
386 "FamilyRoman", "Roman",
387 "FamilyDecorative", "Decorative",
388 "FamilyModern", "Modern",
389 "FamilyTeletype", "Teletype",
390 "FamilySwiss", "Swiss",
391 "FamilyScript", "Script",
392
393 "AfmMedium", "",
394 "AfmBold", "Bo",
395 "AfmLight", "",
396 "AfmStraight", "",
397 "AfmItalic", "${AfmSlant}",
398 "AfmSlant", "O",
399 "AfmRoman", "Ro",
400 "AfmTimes", "Times",
401 "AfmHelvetica", "Helv",
402 "AfmCourier", "Cour",
403
404 "Afm___", "${AfmTimes,$[weight],$[style]}",
405
406 "AfmTimes__", "${AfmTimes}${Afm$[weight]}${Afm$[style]}",
407 "AfmTimesMediumStraight", "${AfmTimes}${AfmRoman}",
408 "AfmTimesLightStraight", "${AfmTimes}${AfmRoman}",
409 "AfmTimes_Italic", "${AfmTimes}$[weight]${AfmItalic}",
410 "AfmTimes_Slant", "${AfmTimes}$[weight]${AfmItalic}",
411
412 "AfmSwiss__", "${AfmHelvetica}${Afm$[weight]}${Afm$[style]}",
413 "AfmModern__", "${AfmCourier}${Afm$[weight]}${Afm$[style]}",
414
415 "AfmTeletype__", "${AfmModern,$[weight],$[style]}",
416
417 "PostScriptMediumStraight", "",
418 "PostScriptMediumItalic", "-Oblique",
419 "PostScriptMediumSlant", "-Oblique",
420 "PostScriptLightStraight", "",
421 "PostScriptLightItalic", "-Oblique",
422 "PostScriptLightSlant", "-Oblique",
423 "PostScriptBoldStraight", "-Bold",
424 "PostScriptBoldItalic", "-BoldOblique",
425 "PostScriptBoldSlant", "-BoldOblique",
426
427#if WX_NORMALIZED_PS_FONTS
428 "PostScript___", "${PostScriptTimes,$[weight],$[style]}",
429#else
430 "PostScriptRoman__", "${PostScriptTimes,$[weight],$[style]}",
431 "PostScript___", "LucidaSans${PostScript$[weight]$[style]}",
432#endif
433
434 "PostScriptTimesMedium", "",
435 "PostScriptTimesLight", "",
436 "PostScriptTimesBold", "Bold",
437
438 "PostScriptTimes__", "Times${PostScript$[weight]$[style]}",
439 "PostScriptTimesMediumStraight", "Times-Roman",
440 "PostScriptTimesLightStraight", "Times-Roman",
441 "PostScriptTimes_Slant", "Times-${PostScriptTimes$[weight]}Italic",
442 "PostScriptTimes_Italic", "Times-${PostScriptTimes$[weight]}Italic",
443
444 "PostScriptSwiss__", "Helvetica${PostScript$[weight]$[style]}",
445 "PostScriptModern__", "Courier${PostScript$[weight]$[style]}",
446
447 "PostScriptTeletype__", "${PostScriptModern,$[weight],$[style]}",
448
449#if !WX_NORMALIZED_PS_FONTS
450 "PostScriptScript__", "Zapf-Chancery-MediumItalic",
451#endif
452
453 "ScreenMedium", "medium",
454 "ScreenBold", "bold",
455 "ScreenLight", "light",
456 "ScreenStraight", "r",
457 "ScreenItalic", "i",
458 "ScreenSlant", "o",
459
460 "ScreenDefaultBase", "misc-fixed",
461 "ScreenRomanBase", "*-times",
462 "ScreenDecorativeBase", "*-helvetica",
463 "ScreenModernBase", "*-courier",
464 "ScreenTeletypeBase", "*-lucidatypewriter",
465 "ScreenSwissBase", "*-lucida",
466 "ScreenScriptBase", "*-zapfchancery",
467
468 "ScreenStdSuffix", "-${Screen$[weight]}-${Screen$[style]}"
469 "-normal-*-*-%d-*-*-*-*-*-*",
470
471 "Screen___",
472 "-${ScreenDefaultBase}${ScreenStdSuffix}",
473 "ScreenRoman__",
474 "-${ScreenRomanBase}${ScreenStdSuffix}",
475 "ScreenDecorative__",
476 "-${ScreenDecorativeBase}${ScreenStdSuffix}",
477 "ScreenModern__",
478 "-${ScreenModernBase}${ScreenStdSuffix}",
479 "ScreenTeletype__",
480 "-${ScreenTeletypeBase}${ScreenStdSuffix}",
481 "ScreenSwiss__",
482 "-${ScreenSwissBase}${ScreenStdSuffix}",
483 "ScreenScript__",
484 "-${ScreenScriptBase}${ScreenStdSuffix}",
c67daf87 485 (char *) NULL
c801d85f
KB
486};
487
488enum {wxWEIGHT_NORMAL, wxWEIGHT_BOLD, wxWEIGHT_LIGHT, wxNUM_WEIGHTS};
489enum {wxSTYLE_NORMAL, wxSTYLE_ITALIC, wxSTYLE_SLANT, wxNUM_STYLES};
490
491static int WCoordinate(int w)
492{
493 switch (w) {
494 case wxBOLD: return wxWEIGHT_BOLD;
495 case wxLIGHT: return wxWEIGHT_LIGHT;
496 case wxNORMAL:
497 default: return wxWEIGHT_NORMAL;
498 }
ff7b1510 499};
c801d85f
KB
500
501static int SCoordinate(int s)
502{
503 switch (s) {
504 case wxITALIC: return wxSTYLE_ITALIC;
505 case wxSLANT: return wxSTYLE_SLANT;
506 case wxNORMAL:
507 default: return wxSTYLE_NORMAL;
508 }
ff7b1510 509};
c801d85f
KB
510
511//-----------------------------------------------------------------------------
512// wxSuffixMap
513//-----------------------------------------------------------------------------
514
515class wxSuffixMap {
516public:
517 ~wxSuffixMap(void);
518
519 inline char *GetName(int weight, int style)
520 {
521 return ( map [WCoordinate(weight)] [SCoordinate(style)] );
522 }
523
524 char *map[wxNUM_WEIGHTS][wxNUM_STYLES];
525 void Initialize(const char *, const char *);
526};
527
528//#if !USE_RESOURCES
529#define wxGetResource(a, b, c) 0
530//#endif
531
532static void SearchResource(const char *prefix, const char **names, int count, char **v)
533{
534 int k, i, j;
535 char resource[1024], **defaults, *internal;
536
537 k = 1 << count;
538
c67daf87
UR
539 *v = (char *) NULL;
540 internal = (char *) NULL;
c801d85f
KB
541
542 for (i = 0; i < k; i++) {
543 strcpy(resource, prefix);
544 for (j = 0; j < count; j++) {
545 if (!(i & (1 << j)))
546 strcat(resource, names[j]);
547 else
548 strcat(resource, "_");
549 }
550 if (wxGetResource(wxAPP_CLASS, (char *)resource, v))
551 return;
552 if (!internal) {
553 defaults = font_defaults;
554 while (*defaults) {
555 if (!strcmp(*defaults, resource)) {
556 internal = defaults[1];
557 break;
558 }
559 defaults += 2;
560 }
561 }
562 }
563 if (internal)
564 *v = copystring(internal);
565}
566
567wxSuffixMap::~wxSuffixMap(void)
568{
569 int k, j;
570
571 for (k = 0; k < wxNUM_WEIGHTS; ++k)
572 for (j = 0; j < wxNUM_STYLES; ++j)
573 if (map[k][j]) {
574 delete[] map[k][j];
c67daf87 575 map[k][j] = (char *) NULL;
c801d85f
KB
576 }
577}
578
579void wxSuffixMap::Initialize(const char *resname, const char *devresname)
580{
581 const char *weight, *style;
582 char *v;
583 int i, j, k;
584 const char *names[3];
585
586 for (k = 0; k < wxNUM_WEIGHTS; k++) {
587 switch (k) {
588 case wxWEIGHT_NORMAL: weight = "Medium"; break;
589 case wxWEIGHT_LIGHT: weight = "Light"; break;
590 case wxWEIGHT_BOLD:
591 default: weight = "Bold";
592 }
593 for (j = 0; j < wxNUM_STYLES; j++) {
594 switch (j) {
595 case wxSTYLE_NORMAL: style = "Straight"; break;
596 case wxSTYLE_ITALIC: style = "Italic"; break;
597 case wxSTYLE_SLANT:
598 default: style = "Slant";
599 }
600 names[0] = resname;
601 names[1] = weight;
602 names[2] = style;
603
604 SearchResource(devresname, names, 3, &v);
605
606 /* Expand macros in the found string: */
607 found:
608 int len, closer = 0, startpos = 0;
609
610 len = (v ? strlen(v) : 0);
611 for (i = 0; i < len; i++) {
612 if (v[i] == '$' && ((v[i+1] == '[') || (v[i+1] == '{'))) {
613 startpos = i;
614 closer = (v[i+1] == '[') ? ']' : '}';
615 ++i;
616 } else if (v[i] == closer) {
617 int newstrlen;
c67daf87 618 const char *r = (char *) NULL; bool delete_r = FALSE;
c801d85f
KB
619 char *name;
620
621 name = v + startpos + 2;
622 v[i] = 0;
623
624 if (closer == '}') {
625 int i, count, len;
626 char **names;
627
628 for (i = 0, count = 1; name[i]; i++)
629 if (name[i] == ',')
630 count++;
631
632 len = i;
633
634 names = new char*[count];
635 names[0] = name;
636 for (i = 0, count = 1; i < len; i++)
637 if (name[i] == ',') {
638 names[count++] = name + i + 1;
639 name[i] = 0;
640 }
641
642 SearchResource("", (const char **)names, count, (char **)&r);
643 delete_r = (r != 0);
644 delete[] names;
645
646 if (!r) {
647 for (i = 0; i < len; i++)
648 if (!name[i])
649 name[i] = ',';
650 r = "";
651 printf("Bad resource name \"%s\" in font lookup\n", name);
652 }
653 } else if (!strcmp(name, "weight")) {
654 r = weight;
655 } else if (!strcmp(name, "style")) {
656 r = style;
657 } else if (!strcmp(name, "family")) {
658 r = resname;
659 } else {
660 r = "";
661 printf("Bad font macro name \"%s\"\n", name);
662 }
663
664 // add r to v
665 newstrlen = strlen(r);
666 char *naya = new char[startpos + newstrlen + len - i];
667 memcpy(naya, v, startpos);
668 memcpy(naya + startpos, r, newstrlen);
669 memcpy(naya + startpos + newstrlen, v + i + 1, len - i);
670 if (delete_r)
671 delete[] (char*)r;
672 delete[] v;
673 v = naya;
674
675 goto found;
676 }
677 }
678 /* We have a final value: */
679 map[k][j] = v;
680 }
681 }
682}
683
684//-----------------------------------------------------------------------------
685// wxFontNameItem
686//-----------------------------------------------------------------------------
687
688class wxFontNameItem : public wxObject {
689DECLARE_DYNAMIC_CLASS(wxFontNameItem)
690public:
691 wxFontNameItem(const char *name, int id, int family);
692 ~wxFontNameItem();
693
694 inline char* GetScreenName(int w, int s) {return screen.GetName(w, s);}
695 inline char* GetPostScriptName(int w, int s) {return printing.GetName(w, s);}
696 inline char* GetAFMName(int w, int s) {return afm.GetName(w, s);}
697 inline char* GetName(void) {return name;}
698 inline int GetFamily(void) {return family;}
699 inline int GetId(void) {return id;}
700 inline bool IsRoman(void) {return isroman;}
701#if WXDEBUG
702 void Dump(ostream& str);
703#endif
704
705 int id;
706 int family;
707 char *name;
708 wxSuffixMap screen, printing, afm;
709 bool isroman;
710};
711
712IMPLEMENT_ABSTRACT_CLASS(wxFontNameItem, wxObject)
713
714wxFontNameItem::wxFontNameItem(const char *Name, int Id, int Family)
715{
716 name = copystring(Name);
717 id = Id;
718 family = Family;
719
720 screen. Initialize(name, "Screen");
721 printing.Initialize(name, "PostScript");
722 afm. Initialize(name, "Afm");
723}
724
725wxFontNameItem::~wxFontNameItem(void)
726{
727 if (name)
728 delete[] name;
c67daf87 729 name = (char *) NULL;
c801d85f
KB
730}
731
732#if WXDEBUG
733void wxFontNameItem::Dump(ostream& str)
734{
735 str << "wxFontNameItem(" << name << ")";
736}
737#endif
738
739//-----------------------------------------------------------------------------
740// wxFontDirectory
741//-----------------------------------------------------------------------------
742
743IMPLEMENT_DYNAMIC_CLASS(wxFontNameDirectory, wxObject)
744
745wxFontNameDirectory::wxFontNameDirectory(void)
746{
747 table = new wxHashTable(wxKEY_INTEGER, 20);
748 nextFontId = -1;
c801d85f
KB
749}
750
751wxFontNameDirectory::~wxFontNameDirectory()
752{
753 // Cleanup wxFontNameItems allocated
754 table->BeginFind();
755 wxNode *node = table->Next();
756 while (node) {
757 wxFontNameItem *item = (wxFontNameItem*)node->Data();
758 delete item;
759 node = table->Next();
760 }
761 delete table;
762}
763
764int wxFontNameDirectory::GetNewFontId(void)
765{
766 return (nextFontId--);
767}
768
769void wxFontNameDirectory::Initialize()
770{
771 Initialize(wxDEFAULT, wxDEFAULT, "Default");
772 Initialize(wxDECORATIVE, wxDECORATIVE, "Decorative");
773 Initialize(wxROMAN, wxROMAN, "Roman");
774 Initialize(wxMODERN, wxMODERN, "Modern");
775 Initialize(wxTELETYPE, wxTELETYPE, "Teletype");
776 Initialize(wxSWISS, wxSWISS, "Swiss");
777 Initialize(wxSCRIPT, wxSCRIPT, "Script");
778}
779
780void wxFontNameDirectory::Initialize(int fontid, int family, const char *resname)
781{
782 char *fam, resource[256];
783
784 sprintf(resource, "Family%s", resname);
c67daf87 785 SearchResource((const char *)resource, (const char **) NULL, 0, (char **)&fam);
c801d85f
KB
786 if (fam) {
787 if (!strcmp(fam, "Default")) family = wxDEFAULT;
788 else if (!strcmp(fam, "Roman")) family = wxROMAN;
789 else if (!strcmp(fam, "Decorative")) family = wxDECORATIVE;
790 else if (!strcmp(fam, "Modern")) family = wxMODERN;
791 else if (!strcmp(fam, "Teletype")) family = wxTELETYPE;
792 else if (!strcmp(fam, "Swiss")) family = wxSWISS;
793 else if (!strcmp(fam, "Script")) family = wxSCRIPT;
794 delete[] fam; // free resource
795 }
796 table->Put(fontid, new wxFontNameItem(resname, fontid, family));
797}
798
799int wxFontNameDirectory::FindOrCreateFontId(const char *name, int family)
800{
801 int id;
802
803 // font exists -> return id
804 if ( (id = GetFontId(name)) ) return id;
805 // create new font
806 Initialize(id=GetNewFontId(), family, name);
807 return id;
808}
809
810char *wxFontNameDirectory::GetScreenName(int fontid, int weight, int style)
811{
812 wxFontNameItem *item = (wxFontNameItem*)table->Get(fontid); // find font
813 if (item)
814 return item->GetScreenName(weight, style);
815 // font does not exist
c67daf87 816 return (char *) NULL;
c801d85f
KB
817}
818
819char *wxFontNameDirectory::GetPostScriptName(int fontid, int weight, int style)
820{
821 wxFontNameItem *item = (wxFontNameItem*)table->Get(fontid); // find font
822 if (item)
823 return item->GetPostScriptName(weight, style);
824 // font does not exist
c67daf87 825 return (char *) NULL;
c801d85f
KB
826}
827
828char *wxFontNameDirectory::GetAFMName(int fontid, int weight, int style)
829{
830 wxFontNameItem *item = (wxFontNameItem *)table->Get(fontid); // find font
831 if (item)
832 return item->GetAFMName(weight, style);
833 // font does not exist
c67daf87 834 return (char *) NULL;
c801d85f
KB
835}
836
837char *wxFontNameDirectory::GetFontName(int fontid)
838{
839 wxFontNameItem *item = (wxFontNameItem *)table->Get(fontid); // find font
840 if (item)
841 return item->GetName();
842 // font does not exist
c67daf87 843 return (char *) NULL;
c801d85f
KB
844}
845
846int wxFontNameDirectory::GetFontId(const char *name)
847{
848 wxNode *node;
849
850 table->BeginFind();
851
852 while ( (node = table->Next()) ) {
853 wxFontNameItem *item = (wxFontNameItem*)node->Data();
854 if (!strcmp(name, item->name))
855 return item->id;
856 }
857 // font does not exist
858 return 0;
859}
860
861int wxFontNameDirectory::GetFamily(int fontid)
862{
863 wxFontNameItem *item = (wxFontNameItem *)table->Get(fontid);
864
865 if (item)
866 return item->family;
867 // font does not exist
868 return wxDEFAULT;
869}