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