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