Back to index

plt-scheme  4.2.1
FontDirectory.cxx
Go to the documentation of this file.
00001 /*                                                      -*- C++ -*-
00002  *
00003  * Purpose: wxWindows font name handling
00004  *
00005  * Authors: Markus Holzem, Julian Smart, and Matthew Flatt
00006  *
00007  * Copyright: (C) 2004-2009 PLT Scheme Inc.
00008  * Copyright: (C) 1995, AIAI, University of Edinburgh (Julian)
00009  * Copyright: (C) 1995, GNU (Markus)
00010  *
00011  * This program is free software; you can redistribute it and/or modify
00012  * it under the terms of the GNU General Public License as published by
00013  * the Free Software Foundation; either version 2 of the License, or
00014  * (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
00024  * USA.
00025  */
00026 
00027 #pragma implementation
00028 
00029 #ifdef wx_xt
00030 # define  Uses_wxApp
00031 # define  Uses_wxFontNameDirectory
00032 # include "wx.h"
00033 # include <string.h>
00034 #endif
00035 
00036 char *font_defaults[] = {
00037   "PostScriptMediumStraight", "",
00038   "PostScriptMediumItalic", "-Oblique",
00039   "PostScriptMediumSlant", "-Oblique",
00040   "PostScriptLightStraight", "",
00041   "PostScriptLightItalic", "-Oblique",
00042   "PostScriptLightSlant", "-Oblique",
00043   "PostScriptBoldStraight", "-Bold",
00044   "PostScriptBoldItalic", "-BoldOblique",
00045   "PostScriptBoldSlant", "-BoldOblique",
00046 
00047   "PostScript___", "${PostScript$[family],$[weight],$[style]}",
00048 
00049   "PostScriptSystem__", "${PostScriptTimes,$[weight],$[style]}",
00050   "PostScriptRoman__", "${PostScriptTimes,$[weight],$[style]}",
00051   "PostScriptScript__", "ZapfChancery-MediumItalic",
00052 
00053   "PostScriptTimesMedium", "",
00054   "PostScriptTimesLight", "",
00055   "PostScriptTimesBold", "Bold",
00056 
00057   "PostScriptTimes__", "Times${PostScript$[weight]$[style]}",
00058   "PostScriptTimesMediumStraight", "Times-Roman",
00059   "PostScriptTimesLightStraight", "Times-Roman",
00060   "PostScriptTimes_Slant", "Times-${PostScriptTimes$[weight]}Italic",
00061   "PostScriptTimes_Italic", "Times-${PostScriptTimes$[weight]}Italic",
00062 
00063   "PostScriptDefault__", "Helvetica${PostScript$[weight]$[style]}",
00064   "PostScriptSwiss__", "Helvetica${PostScript$[weight]$[style]}",
00065   "PostScriptDecorative__", "Helvetica${PostScript$[weight]$[style]}",
00066   "PostScriptModern__", "Courier${PostScript$[weight]$[style]}",
00067   "PostScriptSymbol__", "Symbol",
00068 
00069   "PostScriptTeletype__", "${PostScriptModern,$[weight],$[style]}",
00070 
00071 #ifdef wx_x
00072   "ScreenMedium", "medium",
00073   "ScreenBold", "bold",
00074   "ScreenLight", "light",
00075   "ScreenStraight", "r",
00076   "ScreenItalic", "i",
00077   "ScreenSlant", "o",
00078 
00079   "ScreenSystemBase", "*-lucida",
00080   "ScreenDefaultBase", "*-lucida",
00081   "ScreenRomanBase", "*-times",
00082   "ScreenDecorativeBase", "*-helvetica",
00083   "ScreenModernBase", "*-courier",
00084   "ScreenTeletypeBase", "*-lucidatypewriter",
00085   "ScreenSwissBase", "*-lucida",
00086   "ScreenScriptBase", "*-zapf chancery",
00087   "ScreenSymbolBase", "*-symbol",
00088 
00089   "ScreenStdSuffix", "-${Screen$[weight]}-${Screen$[style]}"
00090     "-normal-*-*-%d-*-*-*-*-*-*",
00091 
00092   "ScreenSystem__",
00093   "+-${ScreenSystemBase}${ScreenStdSuffix}",
00094   "ScreenDefault__",
00095   "+-${ScreenDefaultBase}${ScreenStdSuffix}",
00096   "ScreenRoman__",
00097   "+-${ScreenRomanBase}${ScreenStdSuffix}",
00098   "ScreenDecorative__",
00099   "+-${ScreenDecorativeBase}${ScreenStdSuffix}",
00100   "ScreenModern__",
00101   "+-${ScreenModernBase}${ScreenStdSuffix}",
00102   "ScreenTeletype__",
00103   "+-${ScreenTeletypeBase}${ScreenStdSuffix}",
00104   "ScreenSwiss__",
00105   "+-${ScreenSwissBase}${ScreenStdSuffix}",
00106   "ScreenScript__",
00107   "+-${ScreenScriptBase}-medium-i-normal-*-*-%d-*-*-*-*-*-*",
00108   "ScreenSymbol__",
00109   "+-${ScreenSymbolBase}-medium-r-normal-*-*-%d-*-*-*-*-*-*",
00110 #endif
00111 
00112 #ifdef wx_msw
00113   "ScreenSystem__", "MS Sans Serif", /* maybe changed by Adjust */ 
00114   "ScreenDefault__", "MS Sans Serif", /* maybe changed by Adjust */ 
00115   "ScreenRoman__", "Times New Roman",
00116   "ScreenDecorative__", "Arial",
00117   "ScreenModern__", "Courier New",
00118   "ScreenTeletype__", "${ScreenModern$[weight];$[style]}",
00119   "ScreenSwiss__", "Arial",
00120   "ScreenScript__", "Arial",
00121   "ScreenSymbol__", "Symbol",
00122 #endif
00123 
00124 #ifdef wx_mac
00125 # ifdef OS_X
00126   "ScreenDefault__", "Lucida Grande",
00127   "ScreenSystem__", "Lucida Grande",
00128   "ScreenDecorative__", "Arial", /* "Geneva" looks bad at 12pt in Quartz with QD spacing */
00129   "ScreenModern__", "Courier New", /* "Courier" is worse without Quartz */
00130   "ScreenScript__", "Apple Chancery",
00131 # else
00132   "ScreenDefault__", "applicationfont",
00133   "ScreenSystem__", "systemfont",
00134   "ScreenDecorative__", "Geneva",
00135   "ScreenModern__", "Monaco", /* "courier" is also good */
00136   "ScreenScript__", "Zapf Chancery",
00137 # endif
00138   "ScreenRoman__", "Times",
00139   "ScreenTeletype__", "${ScreenModern,$[weight],$[style]}",
00140   "ScreenSwiss__", "Helvetica",
00141   "ScreenSymbol__", "Symbol",
00142 #endif
00143 
00144   NULL
00145 };
00146 
00147 #ifdef wx_msw
00148 static int CALLBACK check_font_here(ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme,
00149                                    DWORD FontType, LPARAM lParam)
00150 {
00151   *(int *)lParam = 1;
00152   return 0;
00153 }
00154 
00155 int check_avail(char *name)
00156 {
00157   int present = 0;
00158   LOGFONT lf;
00159   HDC dc;
00160   
00161   lf.lfCharSet = DEFAULT_CHARSET;
00162   strcpy(lf.lfFaceName, name);
00163   lf.lfPitchAndFamily = 0;
00164   dc = GetDC(NULL);
00165   EnumFontFamiliesEx(dc, &lf, (FONTENUMPROC)check_font_here, (LPARAM)&present, 0);
00166   ReleaseDC(NULL, dc);
00167 
00168   return present;
00169 }
00170 #endif
00171 
00172 #ifdef WX_USE_XFT
00173 extern int wxXRenderHere(void);
00174 #endif
00175 
00176 static void AdjustFontDefaults(void)
00177 {
00178 #ifdef wx_xt
00179 # ifdef WX_USE_XFT
00180   if (wxXRenderHere()) {
00181     int i;  
00182     
00183     for (i = 0; font_defaults[i]; i += 2) {
00184       if (!strcmp(font_defaults[i], "ScreenSystem__")) {
00185        font_defaults[i + 1] = " Sans";
00186       } else if (!strcmp(font_defaults[i], "ScreenDefault__")) {
00187        font_defaults[i + 1] = " Sans";
00188       } else if (!strcmp(font_defaults[i], "ScreenRoman__")) {
00189        font_defaults[i + 1] = " Serif";
00190       } else if (!strcmp(font_defaults[i], "ScreenDecorative__")) {
00191        font_defaults[i + 1] = " Nimbus Sans L";
00192       } else if (!strcmp(font_defaults[i], "ScreenModern__")) {
00193        font_defaults[i + 1] = " Monospace";
00194       } else if (!strcmp(font_defaults[i], "ScreenTeletype__")) {
00195        font_defaults[i + 1] = " Monospace";
00196       } else if (!strcmp(font_defaults[i], "ScreenSwiss__")) {
00197        font_defaults[i + 1] = " Nimbus Sans L";
00198       } else if (!strcmp(font_defaults[i], "ScreenScript__")) {
00199        font_defaults[i + 1] = " URW Chancery L";
00200       } else if (!strcmp(font_defaults[i], "ScreenSymbol__")) {
00201        font_defaults[i + 1] = " Standard Symbols L,Nimbus Sans L";
00202       }
00203     }
00204   }
00205 # endif
00206 #endif
00207 #ifdef wx_msw
00208   int i;
00209 
00210   for (i = 0; font_defaults[i]; i += 2) {
00211     if (!strcmp(font_defaults[i], "ScreenDefault__")) {
00212       /* We'd prefer to use "Microsoft Sans Serif", instead,
00213         in XP, because that's an outline font. */
00214       if (check_avail("Microsoft Sans Serif")) {
00215        font_defaults[i + 1] = "Microsoft Sans Serif";
00216       }
00217     } else if (!strcmp(font_defaults[i], "ScreenSystem__")) {
00218       /* 2000 and XP use Tahoma by default for controls */
00219       static int known = 0, present = 0;
00220       if (check_avail("Tahoma")) {
00221        font_defaults[i+1] = "Tahoma";
00222       }
00223     }
00224   }
00225 #endif
00226 }
00227 
00228 wxFontNameDirectory *wxTheFontNameDirectory;
00229 
00230 enum {
00231   wxWEIGHT_NORMAL,
00232   wxWEIGHT_BOLD,
00233   wxWEIGHT_LIGHT,
00234   wxNUM_WEIGHTS
00235   };
00236 
00237 enum {
00238   wxSTYLE_NORMAL,
00239   wxSTYLE_ITALIC,
00240   wxSTYLE_SLANT,
00241   wxNUM_STYLES
00242   };
00243 
00244 class wxSuffixMap {
00245  public:
00246   char *map[wxNUM_WEIGHTS][wxNUM_STYLES];
00247   void Initialize(const char *, const char *, int weight, int style, int fam);
00248 
00249   wxSuffixMap();
00250 
00251 #ifdef MZ_PRECISE_GC
00252   void gcMark();
00253   void gcFixup();
00254 #endif
00255 };
00256 
00257 #ifdef MZ_PRECISE_GC
00258 START_XFORM_SKIP;
00259 void wxSuffixMap::gcMark() {
00260   int i, j;
00261   for (i = 0; i < wxNUM_WEIGHTS; i++)
00262     for (j = 0; j < wxNUM_STYLES; j++) {
00263       gcMARK_TYPED(char *, map[i][j]);
00264     }
00265 }
00266 void wxSuffixMap::gcFixup() {
00267   int i, j;
00268   for (i = 0; i < wxNUM_WEIGHTS; i++)
00269     for (j = 0; j < wxNUM_STYLES; j++) {
00270       gcFIXUP_TYPED(char *, map[i][j]);
00271     }
00272 }
00273 END_XFORM_SKIP;
00274 #endif
00275 
00276 wxSuffixMap::wxSuffixMap() {
00277   int i, j;
00278   for (i = 0; i < wxNUM_WEIGHTS; i++) {
00279     for (j = 0; j < wxNUM_STYLES; j++) {
00280       map[i][j] = NULL;
00281     }
00282   }
00283 }
00284 
00285 class wxFontNameItem : public wxObject
00286 {
00287  public:
00288   int id;
00289   int family;
00290   char *name;
00291   wxSuffixMap *screen, *printing;
00292   Bool isfamily;
00293   wxFontNameItem();
00294 };
00295 
00296 wxFontNameItem::wxFontNameItem()
00297 : wxObject(WXGC_NO_CLEANUP)
00298 {
00299   screen = new WXGC_PTRS wxSuffixMap;
00300   printing = new WXGC_PTRS wxSuffixMap;
00301 }
00302 
00303 static int WCoordinate(int w)
00304 {
00305   switch (w) {
00306   case wxBOLD:
00307     return wxWEIGHT_BOLD;
00308   case wxLIGHT:
00309     return wxWEIGHT_LIGHT;
00310   case wxNORMAL:
00311   default:
00312     return wxWEIGHT_NORMAL;
00313   }
00314 }
00315 
00316 static int SCoordinate(int s)
00317 {
00318   switch (s) {
00319   case wxITALIC:
00320     return wxSTYLE_ITALIC;
00321   case wxSLANT:
00322     return wxSTYLE_SLANT;
00323   case wxNORMAL:
00324   default:
00325     return wxSTYLE_NORMAL;
00326   }
00327 }
00328 
00329 wxFontNameDirectory::wxFontNameDirectory(void)
00330 {
00331   wxHashTable *ht;
00332   ht = new WXGC_PTRS wxHashTable(wxKEY_INTEGER, 20);
00333   table = ht;
00334   nextFontId = 100; /* Larger than all family ids */
00335 }
00336 
00337 wxFontNameDirectory::~wxFontNameDirectory()
00338 {
00339   DELETE_OBJ table;
00340 }
00341 
00342 int wxFontNameDirectory::GetNewFontId(void)
00343 {
00344   return (nextFontId++);
00345 }
00346 
00347 int wxGetPreference(const char *name, char *res, long len);
00348 
00349 static char pref_buf[1024];
00350 
00351 static void SearchResource(const char *prefix, const char **names, int count, char **v)
00352 {
00353   int k, i, j;
00354   char resource[1024], *internal;
00355   GC_CAN_IGNORE char **defaults;
00356 
00357   k = 1 << count;
00358 
00359   *v = NULL;
00360   internal = NULL;
00361 
00362   for (i = 0; i < k; i++) {
00363     strcpy(resource, prefix);
00364     for (j = 0; j < count; j++) {
00365       if (!(i & (1 << j)))
00366        strcat(resource, names[j]);
00367       else
00368        strcat(resource, "_");
00369     }
00370 
00371     if (wxGetPreference((char *)resource, pref_buf, 1024) && *pref_buf) {
00372       *v = pref_buf;
00373       return;
00374     }
00375 
00376     if (!internal) {
00377       defaults = font_defaults;
00378       while (*defaults) {
00379        if (!strcmp(*defaults, resource)) {
00380          internal = defaults[1];
00381          break;
00382        }
00383        defaults += 2;
00384       }
00385     }
00386   }
00387 
00388   if (internal) {
00389     char *s;
00390     s = copystring(internal);
00391     *v = s;
00392   }
00393 }
00394 
00395 void wxInitializeFontNameDirectory(void)
00396 {
00397   AdjustFontDefaults();
00398 
00399   wxREGGLOB(wxTheFontNameDirectory);
00400   wxTheFontNameDirectory = new WXGC_PTRS wxFontNameDirectory;
00401   wxTheFontNameDirectory->Initialize(wxSYSTEM, wxSYSTEM, "System");
00402   wxTheFontNameDirectory->Initialize(wxDEFAULT, wxDEFAULT, "Default");
00403   wxTheFontNameDirectory->Initialize(wxDECORATIVE, wxDECORATIVE, "Decorative");
00404   wxTheFontNameDirectory->Initialize(wxROMAN, wxROMAN, "Roman");
00405   wxTheFontNameDirectory->Initialize(wxMODERN, wxMODERN, "Modern");
00406   wxTheFontNameDirectory->Initialize(wxTELETYPE, wxTELETYPE, "Teletype");
00407   wxTheFontNameDirectory->Initialize(wxSWISS, wxSWISS, "Swiss");
00408   wxTheFontNameDirectory->Initialize(wxSCRIPT, wxSCRIPT, "Script");
00409   wxTheFontNameDirectory->Initialize(wxSYMBOL, wxSYMBOL, "Symbol");
00410 }
00411 
00412 void wxSuffixMap::Initialize(const char *resname, const char *devresname,
00413                           int wt, int st, int fam)
00414 {
00415   const char *weight, *style;
00416   char *v = NULL;
00417   int i, drn;
00418 
00419   {
00420     switch (wt) {
00421     case wxWEIGHT_NORMAL:
00422       weight = "Medium";
00423       break;
00424     case wxWEIGHT_LIGHT:
00425       weight = "Light";
00426       break;
00427     case wxWEIGHT_BOLD:
00428       default:
00429       weight = "Bold";
00430     }
00431     {
00432       int len, closer = 0, startpos = 0;
00433       const char *rnames[3];
00434 
00435       switch (st) {
00436       case wxSTYLE_NORMAL:
00437        style = "Straight";
00438        break;
00439       case wxSTYLE_ITALIC:
00440        style = "Italic";
00441        break;
00442       case wxSTYLE_SLANT:
00443       default:
00444        style = "Slant";
00445       }
00446 
00447       rnames[0] = resname;
00448       rnames[1] = weight;
00449       rnames[2] = style;
00450       
00451       SearchResource(devresname, rnames, 3, &v);
00452 
00453       /* Expand macros in the found string: */
00454     found:
00455       len = (v ? strlen(v) : 0);
00456       for (i = 0; i < len; i++) {
00457        if (v[i] == '$' && ((v[i+1] == '[') || (v[i+1] == '{'))) {
00458          startpos = i;
00459          if (v[i+1] == '[')
00460            closer = ']';
00461          else
00462            closer = '}';
00463          i++;
00464        } else if (v[i] == closer) {
00465          int newstrlen, noff;
00466          const char *r = NULL;
00467          char *naya, *name;
00468          
00469          noff = startpos + 2;
00470          name = v;
00471          v[i] = 0;
00472 
00473          if (closer == '}') {
00474            int i, count, len;
00475            char **names;
00476 
00477            for (i = 0, count = 1; name[i + noff]; i++) {
00478              if (name[i + noff] == ',') {
00479               count++;
00480               name[i + noff] = 0;
00481              }
00482            }
00483            
00484            len = i;
00485 
00486            names = new WXGC_PTRS char*[count];
00487 
00488            {
00489              char *cs;
00490              cs = COPYSTRING_TO_ALIGNED(name, noff);
00491              names[0] = cs;
00492            }
00493            for (i = 0, count = 1; i < len; i++) {
00494              if (!name[i + noff]) {
00495               {
00496                 char *cs;
00497                 cs = COPYSTRING_TO_ALIGNED(name, i + 1 + noff);
00498                 names[count++] = cs;
00499               }
00500              }
00501            }
00502 
00503            SearchResource("", (const char **)names, count, (char **)&r);
00504 
00505            if (!r) {
00506              for (i = 0; i < len; i++) {
00507               if (!name[i + noff])
00508                 name[i + noff] = ',';
00509              }
00510              r = "";
00511              printf("Bad resource name \"%s\" in font lookup\n", name + noff);
00512            }
00513          } else if (!strcmp(name + noff, "weight")) {
00514            r = weight;
00515          } else if (!strcmp(name + noff, "style")) {
00516            r = style;
00517          } else if (!strcmp(name + noff, "family")) {
00518            switch (fam) {
00519            case wxSYSTEM:
00520              r = "System";
00521              break;
00522            case wxDECORATIVE:
00523              r = "Decorative";
00524              break;
00525            case wxROMAN:
00526              r = "Roman";
00527              break;
00528            case wxMODERN:
00529              r = "Modern";
00530              break;
00531            case wxTELETYPE:
00532              r = "Teletype";
00533              break;
00534            case wxSWISS:
00535              r = "Swiss";
00536              break;
00537            case wxSCRIPT:
00538              r = "Script";
00539              break;
00540            case wxSYMBOL:
00541              r = "Symbol";
00542              break;
00543            default:
00544              r = "Default";
00545            }
00546          } else {
00547            r = "";
00548            printf("Bad font macro name \"%s\"\n", name + noff);
00549          }
00550          newstrlen = strlen(r);
00551 
00552          naya = new WXGC_ATOMIC char[len + newstrlen + 1];
00553          memcpy(naya, v, startpos);
00554          memcpy(naya + startpos, r, newstrlen);
00555          memcpy(naya + startpos + newstrlen, v + i + 1, len - i + 1);
00556 
00557          v = naya;
00558 
00559          goto found;
00560        }
00561       }
00562 
00563       drn = ((resname[0] == '@') ? 1 : 0);
00564 
00565 #if defined(wx_msw) || defined(wx_mac)
00566       if (!v)
00567        v = copystring(resname + drn);
00568 #endif
00569 #ifdef wx_x
00570       if (!strcmp(devresname, "Screen")) {
00571        if (v && (v[0] == '+')) {
00572          memmove(v, v + 1, strlen(v));
00573        } else {
00574          int len, ds;
00575          char *src;
00576          char *normalcy;
00577          /* Build name using special heuristics:
00578             -([^-]*) => -*-\1-<weight>-<style>-normal-*-*-%d-*-*-*-*-*-*
00579             -([^-]*)-(.*) => -\1-\2-<weight>-<style>-normal-*-*-%d-*-*-*-*-*-*
00580             ([^-].*[^-]) => \1
00581             */
00582 
00583          if (v) {
00584            src = (char *)v;
00585            ds = 0;
00586          } else {
00587            src = (char *)resname;
00588            ds = drn;
00589          }
00590 
00591          len = strlen(src XFORM_OK_PLUS ds);
00592          if (src[ds] == '-') {
00593            char *prefix;
00594            int c = 0;
00595            for (i = 0; i < len; i++) {
00596              if (src[ds + i] == '-')
00597               c++;
00598            }
00599            
00600            v = new WXGC_ATOMIC char[len + 40];
00601            if (c < 2)
00602              prefix = "-*";
00603            else
00604              prefix = "";
00605            
00606            if (c < 3) {
00607              switch (wt) {
00608              case wxWEIGHT_NORMAL:
00609               weight = "-medium";
00610               break;
00611              case wxWEIGHT_LIGHT:
00612               weight = "-light";
00613               break;
00614              case wxWEIGHT_BOLD:
00615              default:
00616               weight = "-bold";
00617              }
00618            } else
00619              weight = "";
00620            
00621            if (c < 4) {
00622              switch (st) {
00623              case wxSTYLE_NORMAL:
00624               style = "-r";
00625              break;
00626              case wxSTYLE_ITALIC:
00627               style = "-i";
00628               break;
00629              case wxSTYLE_SLANT:
00630              default:
00631               style = "-o";
00632              }
00633            } else
00634              style = "";
00635            
00636            if (c < 5)
00637              normalcy = "-normal";
00638            else
00639              normalcy = "";
00640            
00641            sprintf(v, "%s%s%s%s%s-*-*-%%d-*-*-*-*-*-*",
00642                   prefix, src + ds, weight, style, normalcy);
00643          } else
00644            v = COPYSTRING_TO_ALIGNED(src, ds);
00645        }
00646       }
00647 #endif
00648 
00649       /* We have a final value: */
00650       map[wt][st] = v;
00651     }
00652   }
00653 }
00654 
00655 void wxFontNameDirectory::Initialize(int fontid, int family, const char *resname)
00656 {
00657   wxFontNameItem *item;
00658   
00659   item = new WXGC_PTRS wxFontNameItem;
00660 
00661   item->id = fontid;
00662   item->family = family;
00663   item->isfamily = (resname[0] != '@');
00664   item->name = copystring(resname);
00665 
00666   table->Put(fontid, item);
00667 }
00668 
00669 int wxFontNameDirectory::FindOrCreateFontId(const char *name, int family)
00670 {
00671   int id;
00672   char *s;
00673 
00674   if ((id = GetFontId(name, family)))
00675     return id;
00676 
00677   id = GetNewFontId();
00678   s = new WXGC_ATOMIC char[strlen(name) + 2];
00679   strcpy(s + 1, name);
00680   s[0] = '@';
00681   Initialize(id, family, s);
00682 
00683   return id;
00684 }
00685 
00686 char *wxFontNameDirectory::GetScreenName(int fontid, int weight, int style)
00687 {
00688   int wt, st;
00689   wxFontNameItem *item;
00690 
00691   item = (wxFontNameItem *)table->Get(fontid);
00692   
00693   if (!item)
00694     return NULL;
00695 
00696   wt = WCoordinate(weight);
00697   st = SCoordinate(style);
00698 
00699   /* Check for init */
00700   if (!item->screen->map[wt][st])
00701     item->screen->Initialize(item->name, "Screen", wt, st, item->family);
00702 
00703   return item->screen->map[wt][st];
00704 }
00705 
00706 void wxFontNameDirectory::SetScreenName(int fontid, int weight, int style, char *s)
00707 {
00708   int wt, st;
00709   wxFontNameItem *item;
00710 
00711   item = (wxFontNameItem *)table->Get(fontid);
00712   
00713   if (!item)
00714     return;
00715 
00716   wt = WCoordinate(weight);
00717   st = SCoordinate(style);
00718 
00719 #ifdef wx_x
00720   {
00721     /* Safety: name must be less than 500 chars, and must not contain %
00722        except maybe one instance of %d. */
00723     int i, found_d = 0;
00724     for (i = 0; s[i]; i++) {
00725       if (i > 500) {
00726        s = NULL;
00727        break;
00728       }
00729       if (s[i] == '%') {
00730        if (found_d || (s[i+1] != 'd')) {
00731          s = NULL;
00732          break;
00733        } else
00734          found_d = 1;
00735       }
00736     }
00737   }
00738 
00739   if (!s)
00740     return;
00741 #endif
00742 
00743   item->screen->map[wt][st] = s;
00744 }
00745 
00746 char *wxFontNameDirectory::GetPostScriptName(int fontid, int weight, int style)
00747 {
00748   int wt, st;
00749   wxFontNameItem *item;
00750 
00751   item = (wxFontNameItem *)table->Get(fontid);
00752 
00753   if (!item)
00754     return NULL;
00755 
00756   wt = WCoordinate(weight);
00757   st = SCoordinate(style);
00758 
00759   /* Check for init */
00760   if (!item->printing->map[wt][st])
00761     item->printing->Initialize(item->name, "PostScript", wt, st, item->family);
00762 
00763   return item->printing->map[wt][st];
00764 }
00765 
00766 void wxFontNameDirectory::SetPostScriptName(int fontid, int weight, int style, char *s)
00767 {
00768   int wt, st;
00769   wxFontNameItem *item;
00770 
00771   item = (wxFontNameItem *)table->Get(fontid);
00772 
00773   if (!item)
00774     return;
00775 
00776   wt = WCoordinate(weight);
00777   st = SCoordinate(style);
00778 
00779   item->printing->map[wt][st] = s;
00780 }
00781 
00782 char *wxFontNameDirectory::GetFontName(int fontid)
00783 {
00784   wxFontNameItem *item;
00785   item = (wxFontNameItem *)table->Get(fontid);
00786   
00787   if (!item)
00788     return NULL;
00789 
00790   if (item->isfamily)
00791     return NULL;
00792 
00793   return item->name + 1;
00794 }
00795 
00796 int wxFontNameDirectory::GetFontId(const char *name, int family)
00797 {
00798   wxNode *node;
00799 
00800   table->BeginFind();
00801 
00802   while ((node = table->Next())) {
00803     wxFontNameItem *item;
00804     item = (wxFontNameItem *)node->Data();
00805     if (!item->isfamily 
00806        && !strcmp(name, item->name+1)
00807        && item->family == family)
00808       return item->id;
00809   }
00810 
00811   return 0;
00812 }
00813 
00814 int wxFontNameDirectory::GetFamily(int fontid)
00815 {
00816   wxFontNameItem *item;
00817   item = (wxFontNameItem *)table->Get(fontid);
00818   
00819   if (!item)
00820     return wxDEFAULT;
00821 
00822   return item->family;
00823 }
00824 
00825